blob: 8d434110e37582319196703b6f3ca7b8e0c94d99 [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
166 else: # some other output
167 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
YPZhangebf9eb52016-05-12 15:20:24 -0700400 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
kelvin-onlab9f541032015-02-04 16:19:53 -0800408 """
409 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800410 lvlStr = ""
411 if level:
412 lvlStr = "--level=" + level
413
kelvin-onlab338f5512015-02-06 10:53:16 -0800414 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700415 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800416 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800417
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 response = self.handle.before
419 if re.search( "Error", response ):
420 return main.FALSE
421 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700422 except pexpect.TIMEOUT:
423 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700424 if noExit:
425 main.cleanup()
426 return None
427 else:
428 main.cleanup()
429 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800430 except pexpect.EOF:
431 main.log.error( self.name + ": EOF exception found" )
432 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700433 if noExit:
434 main.cleanup()
435 return None
436 else:
437 main.cleanup()
438 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800439 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800440 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit:
442 main.cleanup()
443 return None
444 else:
445 main.cleanup()
446 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400447
YPZhangebf9eb52016-05-12 15:20:24 -0700448 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800449 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800450 Send a completely user specified string to
451 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400452 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800453
YPZhang14a4aa92016-07-15 13:37:15 -0700454 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700455
andrewonlaba18f6bf2014-10-13 19:31:54 -0400456 Warning: There are no sanity checking to commands
457 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800458
kelvin8ec71442015-01-15 16:57:00 -0800459 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400460 try:
Jon Halla495f562016-05-16 18:03:26 -0700461 # Try to reconnect if disconnected from cli
462 self.handle.sendline( "" )
463 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
464 if i == 1:
465 main.log.error( self.name + ": onos cli session closed. ")
466 if self.onosIp:
467 main.log.warn( "Trying to reconnect " + self.onosIp )
468 reconnectResult = self.startOnosCli( self.onosIp )
469 if reconnectResult:
470 main.log.info( self.name + ": onos cli session reconnected." )
471 else:
472 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700473 if noExit:
474 return None
475 else:
476 main.cleanup()
477 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700478 else:
479 main.cleanup()
480 main.exit()
481 if i == 2:
482 self.handle.sendline( "" )
483 self.handle.expect( "onos>" )
484
Jon Hall14a03b52016-05-11 12:07:30 -0700485 if debug:
486 # NOTE: This adds and average of .4 seconds per call
487 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700488 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800489 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800490 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800491 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800492 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800493 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
494 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700495 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700496 main.log.debug( self.name + ": Raw output" )
497 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498
499 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800500 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800501 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700502 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700503 main.log.debug( self.name + ": ansiEscape output" )
504 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505
kelvin-onlabfb521662015-02-27 09:52:40 -0800506 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800507 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": Removed extra returns " +
510 "from output" )
511 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700512
513 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800514 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": parsed and stripped output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
Jon Hall63604932015-02-26 17:09:50 -0800519 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700520 output = response.split( cmdStr.strip(), 1 )
521 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700522 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700524 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800525 output = output[1].strip()
526 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800527 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800528 return output
GlennRCed771242016-01-13 17:02:47 -0800529 except pexpect.TIMEOUT:
530 main.log.error( self.name + ":ONOS timeout" )
531 if debug:
532 main.log.debug( self.handle.before )
533 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 except IndexError:
535 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700536 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700537 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800538 except TypeError:
539 main.log.exception( self.name + ": Object not as expected" )
540 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400541 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800542 main.log.error( self.name + ": EOF exception found" )
543 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700544 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700545 return None
546 else:
547 main.cleanup()
548 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800549 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800550 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700551 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700552 return None
553 else:
554 main.cleanup()
555 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400556
kelvin8ec71442015-01-15 16:57:00 -0800557 # IMPORTANT NOTE:
558 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 # the cli command changing 'a:b' with 'aB'.
560 # Ex ) onos:topology > onosTopology
561 # onos:links > onosLinks
562 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800563
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800565 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 Adds a new cluster node by ID and address information.
567 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 * nodeId
569 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400570 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800572 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400573 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 cmdStr = "add-node " + str( nodeId ) + " " +\
575 str( ONOSIp ) + " " + str( tcpPort )
576 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700577 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800578 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800579 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( "Error in adding node" )
581 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800582 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400583 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400585 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800586 except AssertionError:
587 main.log.exception( "" )
588 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800589 except TypeError:
590 main.log.exception( self.name + ": Object not as expected" )
591 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 main.cleanup()
596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800598 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400599 main.cleanup()
600 main.exit()
601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
andrewonlab86dc3082014-10-13 18:18:38 -0400604 Removes a cluster by ID
605 Issues command: 'remove-node [<node-id>]'
606 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800608 """
andrewonlab86dc3082014-10-13 18:18:38 -0400609 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400610
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700612 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700613 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800614 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700615 if re.search( "Error", handle ):
616 main.log.error( "Error in removing node" )
617 main.log.error( handle )
618 return main.FALSE
619 else:
620 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800621 except AssertionError:
622 main.log.exception( "" )
623 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800624 except TypeError:
625 main.log.exception( self.name + ": Object not as expected" )
626 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400627 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800628 main.log.error( self.name + ": EOF exception found" )
629 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400630 main.cleanup()
631 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800632 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800633 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400634 main.cleanup()
635 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400636
Jon Hall61282e32015-03-19 11:34:11 -0700637 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800638 """
andrewonlab7c211572014-10-15 16:45:20 -0400639 List the nodes currently visible
640 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700641 Optional argument:
642 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800643 """
andrewonlab7c211572014-10-15 16:45:20 -0400644 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700645 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700646 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700647 cmdStr += " -j"
648 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700649 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800650 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700651 return output
Jon Hallc6793552016-01-19 14:18:37 -0800652 except AssertionError:
653 main.log.exception( "" )
654 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800655 except TypeError:
656 main.log.exception( self.name + ": Object not as expected" )
657 return None
andrewonlab7c211572014-10-15 16:45:20 -0400658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800659 main.log.error( self.name + ": EOF exception found" )
660 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400661 main.cleanup()
662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800663 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800664 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400665 main.cleanup()
666 main.exit()
667
kelvin8ec71442015-01-15 16:57:00 -0800668 def topology( self ):
669 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700670 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700671 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700672 Return:
673 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800674 """
andrewonlab95ce8322014-10-13 14:12:04 -0400675 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700676 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800678 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700679 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400680 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800681 except AssertionError:
682 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800683 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800684 except TypeError:
685 main.log.exception( self.name + ": Object not as expected" )
686 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400690 main.cleanup()
691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800692 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800693 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400694 main.cleanup()
695 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800696
jenkins7ead5a82015-03-13 10:28:21 -0700697 def deviceRemove( self, deviceId ):
698 """
699 Removes particular device from storage
700
701 TODO: refactor this function
702 """
703 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700704 cmdStr = "device-remove " + str( deviceId )
705 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800706 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700707 if re.search( "Error", handle ):
708 main.log.error( "Error in removing device" )
709 main.log.error( handle )
710 return main.FALSE
711 else:
712 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800713 except AssertionError:
714 main.log.exception( "" )
715 return None
jenkins7ead5a82015-03-13 10:28:21 -0700716 except TypeError:
717 main.log.exception( self.name + ": Object not as expected" )
718 return None
719 except pexpect.EOF:
720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
722 main.cleanup()
723 main.exit()
724 except Exception:
725 main.log.exception( self.name + ": Uncaught exception!" )
726 main.cleanup()
727 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800730 """
Jon Hall7b02d952014-10-17 20:14:54 -0400731 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400732 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800734 """
andrewonlab86dc3082014-10-13 18:18:38 -0400735 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700736 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700738 cmdStr += " -j"
739 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800740 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800742 except AssertionError:
743 main.log.exception( "" )
744 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800745 except TypeError:
746 main.log.exception( self.name + ": Object not as expected" )
747 return None
andrewonlab7c211572014-10-15 16:45:20 -0400748 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800749 main.log.error( self.name + ": EOF exception found" )
750 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400751 main.cleanup()
752 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800753 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800754 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400755 main.cleanup()
756 main.exit()
757
kelvin-onlabd3b64892015-01-20 13:26:24 -0800758 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800759 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800760 This balances the devices across all controllers
761 by issuing command: 'onos> onos:balance-masters'
762 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800763 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800764 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700766 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800767 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700768 if re.search( "Error", handle ):
769 main.log.error( "Error in balancing masters" )
770 main.log.error( handle )
771 return main.FALSE
772 else:
773 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800774 except AssertionError:
775 main.log.exception( "" )
776 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800777 except TypeError:
778 main.log.exception( self.name + ": Object not as expected" )
779 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800780 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800783 main.cleanup()
784 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800787 main.cleanup()
788 main.exit()
789
Jon Hallc6793552016-01-19 14:18:37 -0800790 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700791 """
792 Returns the output of the masters command.
793 Optional argument:
794 * jsonFormat - boolean indicating if you want output in json
795 """
796 try:
797 cmdStr = "onos:masters"
798 if jsonFormat:
799 cmdStr += " -j"
800 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700801 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800802 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700803 return output
Jon Hallc6793552016-01-19 14:18:37 -0800804 except AssertionError:
805 main.log.exception( "" )
806 return None
acsmars24950022015-07-30 18:00:43 -0700807 except TypeError:
808 main.log.exception( self.name + ": Object not as expected" )
809 return None
810 except pexpect.EOF:
811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
813 main.cleanup()
814 main.exit()
815 except Exception:
816 main.log.exception( self.name + ": Uncaught exception!" )
817 main.cleanup()
818 main.exit()
819
Jon Hallc6793552016-01-19 14:18:37 -0800820 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700821 """
822 Uses the master command to check that the devices' leadership
823 is evenly divided
824
825 Dependencies: checkMasters() and summary()
826
Jon Hall6509dbf2016-06-21 17:01:17 -0700827 Returns main.TRUE if the devices are balanced
828 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700829 Exits on Exception
830 Returns None on TypeError
831 """
832 try:
Jon Hallc6793552016-01-19 14:18:37 -0800833 summaryOutput = self.summary()
834 totalDevices = json.loads( summaryOutput )[ "devices" ]
835 except ( TypeError, ValueError ):
836 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
837 return None
838 try:
acsmars24950022015-07-30 18:00:43 -0700839 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800840 mastersOutput = self.checkMasters()
841 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700842 first = masters[ 0 ][ "size" ]
843 for master in masters:
844 totalOwnedDevices += master[ "size" ]
845 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
846 main.log.error( "Mastership not balanced" )
847 main.log.info( "\n" + self.checkMasters( False ) )
848 return main.FALSE
849 main.log.info( "Mastership balanced between " \
850 + str( len(masters) ) + " masters" )
851 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800852 except ( TypeError, ValueError ):
853 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700854 return None
855 except pexpect.EOF:
856 main.log.error( self.name + ": EOF exception found" )
857 main.log.error( self.name + ": " + self.handle.before )
858 main.cleanup()
859 main.exit()
860 except Exception:
861 main.log.exception( self.name + ": Uncaught exception!" )
862 main.cleanup()
863 main.exit()
864
YPZhangfebf7302016-05-24 16:45:56 -0700865 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800866 """
Jon Halle8217482014-10-17 13:49:14 -0400867 Lists all core links
868 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700872 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700874 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700875 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800876 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800878 except AssertionError:
879 main.log.exception( "" )
880 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800881 except TypeError:
882 main.log.exception( self.name + ": Object not as expected" )
883 return None
Jon Halle8217482014-10-17 13:49:14 -0400884 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800885 main.log.error( self.name + ": EOF exception found" )
886 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400887 main.cleanup()
888 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800889 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800890 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400891 main.cleanup()
892 main.exit()
893
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800895 """
Jon Halle8217482014-10-17 13:49:14 -0400896 Lists all ports
897 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800899 """
Jon Halle8217482014-10-17 13:49:14 -0400900 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700901 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr += " -j"
904 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800905 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800907 except AssertionError:
908 main.log.exception( "" )
909 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800910 except TypeError:
911 main.log.exception( self.name + ": Object not as expected" )
912 return None
Jon Halle8217482014-10-17 13:49:14 -0400913 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800914 main.log.error( self.name + ": EOF exception found" )
915 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400916 main.cleanup()
917 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800918 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800919 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400920 main.cleanup()
921 main.exit()
922
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800924 """
Jon Hall983a1702014-10-28 18:44:22 -0400925 Lists all devices and the controllers with roles assigned to them
926 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800928 """
andrewonlab7c211572014-10-15 16:45:20 -0400929 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700930 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr += " -j"
933 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800934 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700935 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800936 except AssertionError:
937 main.log.exception( "" )
938 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800939 except TypeError:
940 main.log.exception( self.name + ": Object not as expected" )
941 return None
Jon Hall983a1702014-10-28 18:44:22 -0400942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800943 main.log.error( self.name + ": EOF exception found" )
944 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400945 main.cleanup()
946 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800947 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800948 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400949 main.cleanup()
950 main.exit()
951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 Given the a string containing the json representation of the "roles"
955 cli command and a partial or whole device id, returns a json object
956 containing the roles output for the first device whose id contains
957 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400958
959 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800960 A dict of the role assignments for the given device or
961 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Hall983a1702014-10-28 18:44:22 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400965 return None
966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 rawRoles = self.roles()
968 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800969 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800971 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return device
974 return None
Jon Hallc6793552016-01-19 14:18:37 -0800975 except ( TypeError, ValueError ):
976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800977 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400981 main.cleanup()
982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400985 main.cleanup()
986 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800989 """
Jon Hall94fd0472014-12-08 11:52:42 -0800990 Iterates through each device and checks if there is a master assigned
991 Returns: main.TRUE if each device has a master
992 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800993 """
Jon Hall94fd0472014-12-08 11:52:42 -0800994 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 rawRoles = self.roles()
996 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800997 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800999 # print device
1000 if device[ 'master' ] == "none":
1001 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001002 return main.FALSE
1003 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001004 except ( TypeError, ValueError ):
1005 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001006 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001010 main.cleanup()
1011 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001012 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001013 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001014 main.cleanup()
1015 main.exit()
1016
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 Returns string of paths, and the cost.
1020 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001021 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001022 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1024 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001025 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001026 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( "Error in getting paths" )
1028 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 else:
kelvin8ec71442015-01-15 16:57:00 -08001030 path = handle.split( ";" )[ 0 ]
1031 cost = handle.split( ";" )[ 1 ]
1032 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001033 except AssertionError:
1034 main.log.exception( "" )
1035 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001036 except TypeError:
1037 main.log.exception( self.name + ": Object not as expected" )
1038 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001039 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.error( self.name + ": EOF exception found" )
1041 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001042 main.cleanup()
1043 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001044 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001045 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001046 main.cleanup()
1047 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001048
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hallffb386d2014-11-21 13:43:38 -08001051 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001052 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001054 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001056 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001058 cmdStr += " -j"
1059 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001060 if handle:
1061 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001062 # TODO: Maybe make this less hardcoded
1063 # ConsistentMap Exceptions
1064 assert "org.onosproject.store.service" not in handle
1065 # Node not leader
1066 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001068 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001069 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001070 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001071 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001072 except TypeError:
1073 main.log.exception( self.name + ": Object not as expected" )
1074 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001075 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001078 main.cleanup()
1079 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001080 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001081 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001082 main.cleanup()
1083 main.exit()
1084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001088
Jon Hallefbd9792015-03-05 16:11:36 -08001089 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 partial mac address
1091
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001093 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 try:
kelvin8ec71442015-01-15 16:57:00 -08001095 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 return None
1097 else:
1098 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 rawHosts = self.hosts()
1100 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001101 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001103 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001104 if not host:
1105 pass
1106 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001107 return host
1108 return None
Jon Hallc6793552016-01-19 14:18:37 -08001109 except ( TypeError, ValueError ):
1110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001111 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001115 main.cleanup()
1116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001117 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001118 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001119 main.cleanup()
1120 main.exit()
1121
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001123 """
1124 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001125 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001126
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 IMPORTANT:
1130 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001131 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001132 Furthermore, it assumes that value of VLAN is '-1'
1133 Description:
kelvin8ec71442015-01-15 16:57:00 -08001134 Converts mininet hosts ( h1, h2, h3... ) into
1135 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1136 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001141 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 hostHex = hex( int( host ) ).zfill( 12 )
1143 hostHex = str( hostHex ).replace( 'x', '0' )
1144 i = iter( str( hostHex ) )
1145 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1146 hostHex = hostHex + "/-1"
1147 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001150
Jon Halld4d4b372015-01-28 16:02:41 -08001151 except TypeError:
1152 main.log.exception( self.name + ": Object not as expected" )
1153 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001155 main.log.error( self.name + ": EOF exception found" )
1156 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157 main.cleanup()
1158 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001160 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001161 main.cleanup()
1162 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001163
Jeremy Songsterc032f162016-08-04 17:14:49 -07001164 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001165 """
andrewonlabe6745342014-10-17 14:29:13 -04001166 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 * hostIdOne: ONOS host id for host1
1168 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001169 Optional:
1170 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001171 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001172 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001173 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001174 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001175 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001176 Returns:
1177 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001178 """
andrewonlabe6745342014-10-17 14:29:13 -04001179 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001180 cmdStr = "add-host-intent "
1181 if vlanId:
1182 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001183 if setVlan:
1184 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001185 if encap:
1186 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001187 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001189 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001190 if re.search( "Error", handle ):
1191 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001192 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001194 else:
1195 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1197 match = re.search('id=0x([\da-f]+),', handle)
1198 if match:
1199 return match.group()[3:-1]
1200 else:
1201 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001202 main.log.debug( "Response from ONOS was: " +
1203 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001204 return None
Jon Hallc6793552016-01-19 14:18:37 -08001205 except AssertionError:
1206 main.log.exception( "" )
1207 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001208 except TypeError:
1209 main.log.exception( self.name + ": Object not as expected" )
1210 return None
andrewonlabe6745342014-10-17 14:29:13 -04001211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001212 main.log.error( self.name + ": EOF exception found" )
1213 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001214 main.cleanup()
1215 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001217 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001218 main.cleanup()
1219 main.exit()
1220
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001222 """
andrewonlab7b31d232014-10-24 13:31:47 -04001223 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 * ingressDevice: device id of ingress device
1225 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001226 Optional:
1227 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001228 Description:
1229 Adds an optical intent by specifying an ingress and egress device
1230 Returns:
1231 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001232 """
andrewonlab7b31d232014-10-24 13:31:47 -04001233 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1235 " " + str( egressDevice )
1236 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001237 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001238 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001239 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 main.log.error( "Error in adding Optical intent" )
1241 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001242 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001243 main.log.info( "Optical intent installed between " +
1244 str( ingressDevice ) + " and " +
1245 str( egressDevice ) )
1246 match = re.search('id=0x([\da-f]+),', handle)
1247 if match:
1248 return match.group()[3:-1]
1249 else:
1250 main.log.error( "Error, intent ID not found" )
1251 return None
Jon Hallc6793552016-01-19 14:18:37 -08001252 except AssertionError:
1253 main.log.exception( "" )
1254 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001255 except TypeError:
1256 main.log.exception( self.name + ": Object not as expected" )
1257 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001258 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001261 main.cleanup()
1262 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001263 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001264 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001265 main.cleanup()
1266 main.exit()
1267
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 ingressDevice,
1271 egressDevice,
1272 portIngress="",
1273 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 ethType="",
1275 ethSrc="",
1276 ethDst="",
1277 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001279 ipProto="",
1280 ipSrc="",
1281 ipDst="",
1282 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001283 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001284 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001285 setVlan="",
1286 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001287 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001288 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 * ingressDevice: device id of ingress device
1290 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001291 Optional:
1292 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001293 * ethSrc: specify ethSrc ( i.e. src mac addr )
1294 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001295 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001297 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001298 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001299 * ipSrc: specify ip source address
1300 * ipDst: specify ip destination address
1301 * tcpSrc: specify tcp source port
1302 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001303 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001304 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001305 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001306 Description:
kelvin8ec71442015-01-15 16:57:00 -08001307 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001308 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001309 Returns:
1310 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001311
Jon Halle3f39ff2015-01-13 11:50:53 -08001312 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001313 options developers provide for point-to-point
1314 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001316 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001317 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001318
Jeremy Songsterff553672016-05-12 17:06:23 -07001319 if ethType:
1320 cmd += " --ethType " + str( ethType )
1321 if ethSrc:
1322 cmd += " --ethSrc " + str( ethSrc )
1323 if ethDst:
1324 cmd += " --ethDst " + str( ethDst )
1325 if bandwidth:
1326 cmd += " --bandwidth " + str( bandwidth )
1327 if lambdaAlloc:
1328 cmd += " --lambda "
1329 if ipProto:
1330 cmd += " --ipProto " + str( ipProto )
1331 if ipSrc:
1332 cmd += " --ipSrc " + str( ipSrc )
1333 if ipDst:
1334 cmd += " --ipDst " + str( ipDst )
1335 if tcpSrc:
1336 cmd += " --tcpSrc " + str( tcpSrc )
1337 if tcpDst:
1338 cmd += " --tcpDst " + str( tcpDst )
1339 if vlanId:
1340 cmd += " -v " + str( vlanId )
1341 if setVlan:
1342 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001343 if encap:
1344 cmd += " --encapsulation " + str( encap )
andrewonlab289e4b72014-10-21 21:24:18 -04001345
kelvin8ec71442015-01-15 16:57:00 -08001346 # Check whether the user appended the port
1347 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 if "/" in ingressDevice:
1349 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001350 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001352 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001353 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001354 # Would it make sense to throw an exception and exit
1355 # the test?
1356 return None
andrewonlab36af3822014-11-18 17:48:18 -05001357
kelvin8ec71442015-01-15 16:57:00 -08001358 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 str( ingressDevice ) + "/" +\
1360 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001361
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 if "/" in egressDevice:
1363 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001364 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001366 main.log.error( "You must specify the egress port" )
1367 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001368
kelvin8ec71442015-01-15 16:57:00 -08001369 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001370 str( egressDevice ) + "/" +\
1371 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001372
kelvin-onlab898a6c62015-01-16 14:13:53 -08001373 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001374 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001375 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001377 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001379 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 # TODO: print out all the options in this message?
1381 main.log.info( "Point-to-point intent installed between " +
1382 str( ingressDevice ) + " and " +
1383 str( egressDevice ) )
1384 match = re.search('id=0x([\da-f]+),', handle)
1385 if match:
1386 return match.group()[3:-1]
1387 else:
1388 main.log.error( "Error, intent ID not found" )
1389 return None
Jon Hallc6793552016-01-19 14:18:37 -08001390 except AssertionError:
1391 main.log.exception( "" )
1392 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001393 except TypeError:
1394 main.log.exception( self.name + ": Object not as expected" )
1395 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001397 main.log.error( self.name + ": EOF exception found" )
1398 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001399 main.cleanup()
1400 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001401 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001402 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001403 main.cleanup()
1404 main.exit()
1405
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001407 self,
shahshreyac2f97072015-03-19 17:04:29 -07001408 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001409 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001410 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001412 ethType="",
1413 ethSrc="",
1414 ethDst="",
1415 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001417 ipProto="",
1418 ipSrc="",
1419 ipDst="",
1420 tcpSrc="",
1421 tcpDst="",
1422 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001423 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001424 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001425 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001426 partial=False,
1427 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001428 """
shahshreyad0c80432014-12-04 16:56:05 -08001429 Note:
shahshreya70622b12015-03-19 17:19:00 -07001430 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001431 is same. That is, all ingress devices include port numbers
1432 with a "/" or all ingress devices could specify device
1433 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001434 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001435 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001436 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001438 Optional:
1439 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001440 * ethSrc: specify ethSrc ( i.e. src mac addr )
1441 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001442 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001444 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001445 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001446 * ipSrc: specify ip source address
1447 * ipDst: specify ip destination address
1448 * tcpSrc: specify tcp source port
1449 * tcpDst: specify tcp destination port
1450 * setEthSrc: action to Rewrite Source MAC Address
1451 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001452 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001453 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001454 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001455 Description:
kelvin8ec71442015-01-15 16:57:00 -08001456 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001457 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001458 Returns:
1459 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001460
Jon Halle3f39ff2015-01-13 11:50:53 -08001461 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001462 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001463 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001464 """
shahshreyad0c80432014-12-04 16:56:05 -08001465 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001466 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001467
Jeremy Songsterff553672016-05-12 17:06:23 -07001468 if ethType:
1469 cmd += " --ethType " + str( ethType )
1470 if ethSrc:
1471 cmd += " --ethSrc " + str( ethSrc )
1472 if ethDst:
1473 cmd += " --ethDst " + str( ethDst )
1474 if bandwidth:
1475 cmd += " --bandwidth " + str( bandwidth )
1476 if lambdaAlloc:
1477 cmd += " --lambda "
1478 if ipProto:
1479 cmd += " --ipProto " + str( ipProto )
1480 if ipSrc:
1481 cmd += " --ipSrc " + str( ipSrc )
1482 if ipDst:
1483 cmd += " --ipDst " + str( ipDst )
1484 if tcpSrc:
1485 cmd += " --tcpSrc " + str( tcpSrc )
1486 if tcpDst:
1487 cmd += " --tcpDst " + str( tcpDst )
1488 if setEthSrc:
1489 cmd += " --setEthSrc " + str( setEthSrc )
1490 if setEthDst:
1491 cmd += " --setEthDst " + str( setEthDst )
1492 if vlanId:
1493 cmd += " -v " + str( vlanId )
1494 if setVlan:
1495 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001496 if partial:
1497 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001498 if encap:
1499 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001500
kelvin8ec71442015-01-15 16:57:00 -08001501 # Check whether the user appended the port
1502 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001503
1504 if portIngressList is None:
1505 for ingressDevice in ingressDeviceList:
1506 if "/" in ingressDevice:
1507 cmd += " " + str( ingressDevice )
1508 else:
1509 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001510 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001511 # TODO: perhaps more meaningful return
1512 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001513 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001514 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001515 for ingressDevice, portIngress in zip( ingressDeviceList,
1516 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001517 cmd += " " + \
1518 str( ingressDevice ) + "/" +\
1519 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001520 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001521 main.log.error( "Device list and port list does not " +
1522 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001523 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 if "/" in egressDevice:
1525 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001526 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001528 main.log.error( "You must specify " +
1529 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001530 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001531
kelvin8ec71442015-01-15 16:57:00 -08001532 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 str( egressDevice ) + "/" +\
1534 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001535 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001536 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001537 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001538 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001539 main.log.error( "Error in adding multipoint-to-singlepoint " +
1540 "intent" )
1541 return None
shahshreyad0c80432014-12-04 16:56:05 -08001542 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001543 match = re.search('id=0x([\da-f]+),', handle)
1544 if match:
1545 return match.group()[3:-1]
1546 else:
1547 main.log.error( "Error, intent ID not found" )
1548 return None
Jon Hallc6793552016-01-19 14:18:37 -08001549 except AssertionError:
1550 main.log.exception( "" )
1551 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001552 except TypeError:
1553 main.log.exception( self.name + ": Object not as expected" )
1554 return None
1555 except pexpect.EOF:
1556 main.log.error( self.name + ": EOF exception found" )
1557 main.log.error( self.name + ": " + self.handle.before )
1558 main.cleanup()
1559 main.exit()
1560 except Exception:
1561 main.log.exception( self.name + ": Uncaught exception!" )
1562 main.cleanup()
1563 main.exit()
1564
1565 def addSinglepointToMultipointIntent(
1566 self,
1567 ingressDevice,
1568 egressDeviceList,
1569 portIngress="",
1570 portEgressList=None,
1571 ethType="",
1572 ethSrc="",
1573 ethDst="",
1574 bandwidth="",
1575 lambdaAlloc=False,
1576 ipProto="",
1577 ipSrc="",
1578 ipDst="",
1579 tcpSrc="",
1580 tcpDst="",
1581 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001582 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001583 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001584 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001585 partial=False,
1586 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001587 """
1588 Note:
1589 This function assumes the format of all egress devices
1590 is same. That is, all egress devices include port numbers
1591 with a "/" or all egress devices could specify device
1592 ids and port numbers seperately.
1593 Required:
1594 * EgressDeviceList: List of device ids of egress device
1595 ( Atleast 2 eress devices required in the list )
1596 * ingressDevice: device id of ingress device
1597 Optional:
1598 * ethType: specify ethType
1599 * ethSrc: specify ethSrc ( i.e. src mac addr )
1600 * ethDst: specify ethDst ( i.e. dst mac addr )
1601 * bandwidth: specify bandwidth capacity of link
1602 * lambdaAlloc: if True, intent will allocate lambda
1603 for the specified intent
1604 * ipProto: specify ip protocol
1605 * ipSrc: specify ip source address
1606 * ipDst: specify ip destination address
1607 * tcpSrc: specify tcp source port
1608 * tcpDst: specify tcp destination port
1609 * setEthSrc: action to Rewrite Source MAC Address
1610 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001611 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001612 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001613 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001614 Description:
1615 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1616 specifying device id's and optional fields
1617 Returns:
1618 A string of the intent id or None on error
1619
1620 NOTE: This function may change depending on the
1621 options developers provide for singlepoint-to-multipoint
1622 intent via cli
1623 """
1624 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001625 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001626
Jeremy Songsterff553672016-05-12 17:06:23 -07001627 if ethType:
1628 cmd += " --ethType " + str( ethType )
1629 if ethSrc:
1630 cmd += " --ethSrc " + str( ethSrc )
1631 if ethDst:
1632 cmd += " --ethDst " + str( ethDst )
1633 if bandwidth:
1634 cmd += " --bandwidth " + str( bandwidth )
1635 if lambdaAlloc:
1636 cmd += " --lambda "
1637 if ipProto:
1638 cmd += " --ipProto " + str( ipProto )
1639 if ipSrc:
1640 cmd += " --ipSrc " + str( ipSrc )
1641 if ipDst:
1642 cmd += " --ipDst " + str( ipDst )
1643 if tcpSrc:
1644 cmd += " --tcpSrc " + str( tcpSrc )
1645 if tcpDst:
1646 cmd += " --tcpDst " + str( tcpDst )
1647 if setEthSrc:
1648 cmd += " --setEthSrc " + str( setEthSrc )
1649 if setEthDst:
1650 cmd += " --setEthDst " + str( setEthDst )
1651 if vlanId:
1652 cmd += " -v " + str( vlanId )
1653 if setVlan:
1654 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001655 if partial:
1656 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001657 if encap:
1658 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001659
1660 # Check whether the user appended the port
1661 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001662
kelvin-onlabb9408212015-04-01 13:34:04 -07001663 if "/" in ingressDevice:
1664 cmd += " " + str( ingressDevice )
1665 else:
1666 if not portIngress:
1667 main.log.error( "You must specify " +
1668 "the Ingress port" )
1669 return main.FALSE
1670
1671 cmd += " " +\
1672 str( ingressDevice ) + "/" +\
1673 str( portIngress )
1674
1675 if portEgressList is None:
1676 for egressDevice in egressDeviceList:
1677 if "/" in egressDevice:
1678 cmd += " " + str( egressDevice )
1679 else:
1680 main.log.error( "You must specify " +
1681 "the egress port" )
1682 # TODO: perhaps more meaningful return
1683 return main.FALSE
1684 else:
1685 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001686 for egressDevice, portEgress in zip( egressDeviceList,
1687 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 cmd += " " + \
1689 str( egressDevice ) + "/" +\
1690 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001691 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001692 main.log.error( "Device list and port list does not " +
1693 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001694 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001695 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001696 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001697 # If error, return error message
1698 if re.search( "Error", handle ):
1699 main.log.error( "Error in adding singlepoint-to-multipoint " +
1700 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001701 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001702 else:
1703 match = re.search('id=0x([\da-f]+),', handle)
1704 if match:
1705 return match.group()[3:-1]
1706 else:
1707 main.log.error( "Error, intent ID not found" )
1708 return None
Jon Hallc6793552016-01-19 14:18:37 -08001709 except AssertionError:
1710 main.log.exception( "" )
1711 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001712 except TypeError:
1713 main.log.exception( self.name + ": Object not as expected" )
1714 return None
shahshreyad0c80432014-12-04 16:56:05 -08001715 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001716 main.log.error( self.name + ": EOF exception found" )
1717 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001718 main.cleanup()
1719 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001720 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001721 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001722 main.cleanup()
1723 main.exit()
1724
Hari Krishna9e232602015-04-13 17:29:08 -07001725 def addMplsIntent(
1726 self,
1727 ingressDevice,
1728 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001729 ingressPort="",
1730 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001731 ethType="",
1732 ethSrc="",
1733 ethDst="",
1734 bandwidth="",
1735 lambdaAlloc=False,
1736 ipProto="",
1737 ipSrc="",
1738 ipDst="",
1739 tcpSrc="",
1740 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001741 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001742 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001743 priority=""):
1744 """
1745 Required:
1746 * ingressDevice: device id of ingress device
1747 * egressDevice: device id of egress device
1748 Optional:
1749 * ethType: specify ethType
1750 * ethSrc: specify ethSrc ( i.e. src mac addr )
1751 * ethDst: specify ethDst ( i.e. dst mac addr )
1752 * bandwidth: specify bandwidth capacity of link
1753 * lambdaAlloc: if True, intent will allocate lambda
1754 for the specified intent
1755 * ipProto: specify ip protocol
1756 * ipSrc: specify ip source address
1757 * ipDst: specify ip destination address
1758 * tcpSrc: specify tcp source port
1759 * tcpDst: specify tcp destination port
1760 * ingressLabel: Ingress MPLS label
1761 * egressLabel: Egress MPLS label
1762 Description:
1763 Adds MPLS intent by
1764 specifying device id's and optional fields
1765 Returns:
1766 A string of the intent id or None on error
1767
1768 NOTE: This function may change depending on the
1769 options developers provide for MPLS
1770 intent via cli
1771 """
1772 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001773 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001774
Jeremy Songsterff553672016-05-12 17:06:23 -07001775 if ethType:
1776 cmd += " --ethType " + str( ethType )
1777 if ethSrc:
1778 cmd += " --ethSrc " + str( ethSrc )
1779 if ethDst:
1780 cmd += " --ethDst " + str( ethDst )
1781 if bandwidth:
1782 cmd += " --bandwidth " + str( bandwidth )
1783 if lambdaAlloc:
1784 cmd += " --lambda "
1785 if ipProto:
1786 cmd += " --ipProto " + str( ipProto )
1787 if ipSrc:
1788 cmd += " --ipSrc " + str( ipSrc )
1789 if ipDst:
1790 cmd += " --ipDst " + str( ipDst )
1791 if tcpSrc:
1792 cmd += " --tcpSrc " + str( tcpSrc )
1793 if tcpDst:
1794 cmd += " --tcpDst " + str( tcpDst )
1795 if ingressLabel:
1796 cmd += " --ingressLabel " + str( ingressLabel )
1797 if egressLabel:
1798 cmd += " --egressLabel " + str( egressLabel )
1799 if priority:
1800 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001801
1802 # Check whether the user appended the port
1803 # or provided it as an input
1804 if "/" in ingressDevice:
1805 cmd += " " + str( ingressDevice )
1806 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001807 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001808 main.log.error( "You must specify the ingress port" )
1809 return None
1810
1811 cmd += " " + \
1812 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001813 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001814
1815 if "/" in egressDevice:
1816 cmd += " " + str( egressDevice )
1817 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001818 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001819 main.log.error( "You must specify the egress port" )
1820 return None
1821
1822 cmd += " " +\
1823 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001824 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001825
1826 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001827 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001828 # If error, return error message
1829 if re.search( "Error", handle ):
1830 main.log.error( "Error in adding mpls intent" )
1831 return None
1832 else:
1833 # TODO: print out all the options in this message?
1834 main.log.info( "MPLS intent installed between " +
1835 str( ingressDevice ) + " and " +
1836 str( egressDevice ) )
1837 match = re.search('id=0x([\da-f]+),', handle)
1838 if match:
1839 return match.group()[3:-1]
1840 else:
1841 main.log.error( "Error, intent ID not found" )
1842 return None
Jon Hallc6793552016-01-19 14:18:37 -08001843 except AssertionError:
1844 main.log.exception( "" )
1845 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001846 except TypeError:
1847 main.log.exception( self.name + ": Object not as expected" )
1848 return None
1849 except pexpect.EOF:
1850 main.log.error( self.name + ": EOF exception found" )
1851 main.log.error( self.name + ": " + self.handle.before )
1852 main.cleanup()
1853 main.exit()
1854 except Exception:
1855 main.log.exception( self.name + ": Uncaught exception!" )
1856 main.cleanup()
1857 main.exit()
1858
Jon Hallefbd9792015-03-05 16:11:36 -08001859 def removeIntent( self, intentId, app='org.onosproject.cli',
1860 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 """
shahshreya1c818fc2015-02-26 13:44:08 -08001862 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001863 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001864 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001865 -p or --purge: Purge the intent from the store after removal
1866
Jon Halle3f39ff2015-01-13 11:50:53 -08001867 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001868 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001869 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001871 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001872 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001873 if purge:
1874 cmdStr += " -p"
1875 if sync:
1876 cmdStr += " -s"
1877
1878 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001880 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001881 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001883 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001884 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001885 # TODO: Should this be main.TRUE
1886 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001887 except AssertionError:
1888 main.log.exception( "" )
1889 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001890 except TypeError:
1891 main.log.exception( self.name + ": Object not as expected" )
1892 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001894 main.log.error( self.name + ": EOF exception found" )
1895 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001896 main.cleanup()
1897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001899 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001900 main.cleanup()
1901 main.exit()
1902
YPZhangfebf7302016-05-24 16:45:56 -07001903 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001904 """
1905 Description:
1906 Remove all the intents
1907 Optional args:-
1908 -s or --sync: Waits for the removal before returning
1909 -p or --purge: Purge the intent from the store after removal
1910 Returns:
1911 Returns main.TRUE if all intents are removed, otherwise returns
1912 main.FALSE; Returns None for exception
1913 """
1914 try:
1915 cmdStr = "remove-intent"
1916 if purge:
1917 cmdStr += " -p"
1918 if sync:
1919 cmdStr += " -s"
1920
1921 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001922 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001923 assert "Command not found:" not in handle, handle
1924 if re.search( "Error", handle ):
1925 main.log.error( "Error in removing intent" )
1926 return main.FALSE
1927 else:
1928 return main.TRUE
1929 except AssertionError:
1930 main.log.exception( "" )
1931 return None
1932 except TypeError:
1933 main.log.exception( self.name + ": Object not as expected" )
1934 return None
1935 except pexpect.EOF:
1936 main.log.error( self.name + ": EOF exception found" )
1937 main.log.error( self.name + ": " + self.handle.before )
1938 main.cleanup()
1939 main.exit()
1940 except Exception:
1941 main.log.exception( self.name + ": Uncaught exception!" )
1942 main.cleanup()
1943 main.exit()
1944
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001945 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001946 """
1947 Purges all WITHDRAWN Intents
1948 """
1949 try:
1950 cmdStr = "purge-intents"
1951 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001952 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001953 if re.search( "Error", handle ):
1954 main.log.error( "Error in purging intents" )
1955 return main.FALSE
1956 else:
1957 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001958 except AssertionError:
1959 main.log.exception( "" )
1960 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001961 except TypeError:
1962 main.log.exception( self.name + ": Object not as expected" )
1963 return None
1964 except pexpect.EOF:
1965 main.log.error( self.name + ": EOF exception found" )
1966 main.log.error( self.name + ": " + self.handle.before )
1967 main.cleanup()
1968 main.exit()
1969 except Exception:
1970 main.log.exception( self.name + ": Uncaught exception!" )
1971 main.cleanup()
1972 main.exit()
1973
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001975 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001976 NOTE: This method should be used after installing application:
1977 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001979 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001980 Description:
1981 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001982 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001983 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001984 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001985 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001986 cmdStr += " -j"
1987 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001988 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001989 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001990 except AssertionError:
1991 main.log.exception( "" )
1992 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001993 except TypeError:
1994 main.log.exception( self.name + ": Object not as expected" )
1995 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001997 main.log.error( self.name + ": EOF exception found" )
1998 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001999 main.cleanup()
2000 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002001 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002002 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002003 main.cleanup()
2004 main.exit()
2005
pingping-lin54b03372015-08-13 14:43:10 -07002006 def ipv4RouteNumber( self ):
2007 """
2008 NOTE: This method should be used after installing application:
2009 onos-app-sdnip
2010 Description:
2011 Obtain the total IPv4 routes number in the system
2012 """
2013 try:
2014 cmdStr = "routes -s -j"
2015 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002016 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002017 jsonResult = json.loads( handle )
2018 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002019 except AssertionError:
2020 main.log.exception( "" )
2021 return None
2022 except ( TypeError, ValueError ):
2023 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002024 return None
2025 except pexpect.EOF:
2026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
2028 main.cleanup()
2029 main.exit()
2030 except Exception:
2031 main.log.exception( self.name + ": Uncaught exception!" )
2032 main.cleanup()
2033 main.exit()
2034
pingping-lin8244a3b2015-09-16 13:36:56 -07002035 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002036 """
andrewonlabe6745342014-10-17 14:29:13 -04002037 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002038 Obtain intents from the ONOS cli.
2039 Optional:
2040 * jsonFormat: Enable output formatting in json, default to True
2041 * summary: Whether only output the intent summary, defaults to False
2042 * type: Only output a certain type of intent. This options is valid
2043 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002044 """
andrewonlabe6745342014-10-17 14:29:13 -04002045 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002046 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002047 if summary:
2048 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002049 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002050 cmdStr += " -j"
2051 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002052 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002053 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002054 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002055 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002056 else:
Jon Hallff566d52016-01-15 14:45:36 -08002057 intentType = ""
2058 # IF we want the summary of a specific intent type
2059 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002060 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002061 if intentType in jsonResult.keys():
2062 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002063 else:
Jon Hallff566d52016-01-15 14:45:36 -08002064 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002065 return handle
2066 else:
2067 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002068 except AssertionError:
2069 main.log.exception( "" )
2070 return None
2071 except ( TypeError, ValueError ):
2072 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002073 return None
2074 except pexpect.EOF:
2075 main.log.error( self.name + ": EOF exception found" )
2076 main.log.error( self.name + ": " + self.handle.before )
2077 main.cleanup()
2078 main.exit()
2079 except Exception:
2080 main.log.exception( self.name + ": Uncaught exception!" )
2081 main.cleanup()
2082 main.exit()
2083
kelvin-onlab54400a92015-02-26 18:05:51 -08002084 def getIntentState(self, intentsId, intentsJson=None):
2085 """
You Wangfdcbfc42016-05-16 12:16:53 -07002086 Description:
2087 Gets intent state. Accepts a single intent ID (string type) or a
2088 list of intent IDs.
2089 Parameters:
2090 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002091 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002092 Returns:
2093 Returns the state (string type) of the ID if a single intent ID is
2094 accepted.
2095 Returns a list of dictionaries if a list of intent IDs is accepted,
2096 and each dictionary maps 'id' to the Intent ID and 'state' to
2097 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002098 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002099 try:
2100 state = "State is Undefined"
2101 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002102 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002103 else:
Jon Hallc6793552016-01-19 14:18:37 -08002104 rawJson = intentsJson
2105 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002106 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002107 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002108 if intentsId == intent[ 'id' ]:
2109 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002110 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002111 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2112 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002114 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002115 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002116 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002117 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002118 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002119 if intentsId[ i ] == intents[ 'id' ]:
2120 stateDict[ 'state' ] = intents[ 'state' ]
2121 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002122 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002123 break
Jon Hallefbd9792015-03-05 16:11:36 -08002124 if len( intentsId ) != len( dictList ):
2125 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002126 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002127 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002128 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002129 return None
Jon Hallc6793552016-01-19 14:18:37 -08002130 except ( TypeError, ValueError ):
2131 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002132 return None
2133 except pexpect.EOF:
2134 main.log.error( self.name + ": EOF exception found" )
2135 main.log.error( self.name + ": " + self.handle.before )
2136 main.cleanup()
2137 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002138 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002140 main.cleanup()
2141 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002142
kelvin-onlabf512e942015-06-08 19:42:59 -07002143 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002144 """
2145 Description:
2146 Check intents state
2147 Required:
2148 intentsId - List of intents ID to be checked
2149 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002150 expectedState - Check the expected state(s) of each intents
2151 state in the list.
2152 *NOTE: You can pass in a list of expected state,
2153 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002154 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002155 Returns main.TRUE only if all intent are the same as expected states
2156 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002157 """
2158 try:
2159 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002160 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002161 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002162 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002163 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002164 "getting intents state" )
2165 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002166
2167 if isinstance( expectedState, types.StringType ):
2168 for intents in intentsDict:
2169 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002170 main.log.debug( self.name + " : Intent ID - " +
2171 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002172 " actual state = " +
2173 intents.get( 'state' )
2174 + " does not equal expected state = "
2175 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002176 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002177
2178 elif isinstance( expectedState, types.ListType ):
2179 for intents in intentsDict:
2180 if not any( state == intents.get( 'state' ) for state in
2181 expectedState ):
2182 main.log.debug( self.name + " : Intent ID - " +
2183 intents.get( 'id' ) +
2184 " actual state = " +
2185 intents.get( 'state' ) +
2186 " does not equal expected states = "
2187 + str( expectedState ) )
2188 returnValue = main.FALSE
2189
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002190 if returnValue == main.TRUE:
2191 main.log.info( self.name + ": All " +
2192 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002193 " intents are in " + str( expectedState ) +
2194 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002195 return returnValue
2196 except TypeError:
2197 main.log.exception( self.name + ": Object not as expected" )
2198 return None
2199 except pexpect.EOF:
2200 main.log.error( self.name + ": EOF exception found" )
2201 main.log.error( self.name + ": " + self.handle.before )
2202 main.cleanup()
2203 main.exit()
2204 except Exception:
2205 main.log.exception( self.name + ": Uncaught exception!" )
2206 main.cleanup()
2207 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002208
You Wang66518af2016-05-16 15:32:59 -07002209 def compareIntent( self, intentDict ):
2210 """
2211 Description:
2212 Compare the intent ids and states provided in the argument with all intents in ONOS
2213 Return:
2214 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2215 Arguments:
2216 intentDict: a dictionary which maps intent ids to intent states
2217 """
2218 try:
2219 intentsRaw = self.intents()
2220 intentsJson = json.loads( intentsRaw )
2221 intentDictONOS = {}
2222 for intent in intentsJson:
2223 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002224 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002225 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002226 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002227 str( len( intentDict ) ) + " expected and " +
2228 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002229 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002230 for intentID in intentDict.keys():
2231 if not intentID in intentDictONOS.keys():
2232 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2233 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002234 else:
2235 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2236 main.log.debug( self.name + ": intent ID - " + intentID +
2237 " expected state is " + intentDict[ intentID ] +
2238 " but actual state is " + intentDictONOS[ intentID ] )
2239 returnValue = main.FALSE
2240 intentDictONOS.pop( intentID )
2241 if len( intentDictONOS ) > 0:
2242 returnValue = main.FALSE
2243 for intentID in intentDictONOS.keys():
2244 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002245 if returnValue == main.TRUE:
2246 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2247 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002248 except KeyError:
2249 main.log.exception( self.name + ": KeyError exception found" )
2250 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002251 except ( TypeError, ValueError ):
2252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002253 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002254 except pexpect.EOF:
2255 main.log.error( self.name + ": EOF exception found" )
2256 main.log.error( self.name + ": " + self.handle.before )
2257 main.cleanup()
2258 main.exit()
2259 except Exception:
2260 main.log.exception( self.name + ": Uncaught exception!" )
2261 main.cleanup()
2262 main.exit()
2263
YPZhang14a4aa92016-07-15 13:37:15 -07002264 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002265 """
2266 Description:
2267 Check the number of installed intents.
2268 Optional:
2269 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002270 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002271 Return:
2272 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2273 , otherwise, returns main.FALSE.
2274 """
2275
2276 try:
2277 cmd = "intents -s -j"
2278
2279 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002280 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002281 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002282 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002283 response = json.loads( response )
2284
2285 # get total and installed number, see if they are match
2286 allState = response.get( 'all' )
2287 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002288 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002289 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002290 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002291 return main.FALSE
2292
Jon Hallc6793552016-01-19 14:18:37 -08002293 except ( TypeError, ValueError ):
2294 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002295 return None
2296 except pexpect.EOF:
2297 main.log.error( self.name + ": EOF exception found" )
2298 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002299 if noExit:
2300 return main.FALSE
2301 else:
2302 main.cleanup()
2303 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002304 except Exception:
2305 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002306 if noExit:
2307 return main.FALSE
2308 else:
2309 main.cleanup()
2310 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002311 except pexpect.TIMEOUT:
2312 main.log.error( self.name + ": ONOS timeout" )
2313 return None
GlennRCed771242016-01-13 17:02:47 -08002314
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002315 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002316 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002317 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002318 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002319 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002320 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002321 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002322 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002323 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002324 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002325 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002326 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002327 if noCore:
2328 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002329 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002330 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002331 assert "Command not found:" not in handle, handle
2332 if re.search( "Error:", handle ):
2333 main.log.error( self.name + ": flows() response: " +
2334 str( handle ) )
2335 return handle
2336 except AssertionError:
2337 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002338 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002339 except TypeError:
2340 main.log.exception( self.name + ": Object not as expected" )
2341 return None
Jon Hallc6793552016-01-19 14:18:37 -08002342 except pexpect.TIMEOUT:
2343 main.log.error( self.name + ": ONOS timeout" )
2344 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002348 main.cleanup()
2349 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002350 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002351 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002352 main.cleanup()
2353 main.exit()
2354
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002355 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002356 count = self.getTotalFlowsNum( timeout=timeout )
2357 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002358 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002359
YPZhangebf9eb52016-05-12 15:20:24 -07002360 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002361 """
2362 Description:
GlennRCed771242016-01-13 17:02:47 -08002363 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002364 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2365 if the count of those states is 0, which means all current flows
2366 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002367 Optional:
GlennRCed771242016-01-13 17:02:47 -08002368 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002369 Return:
2370 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002371 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002372 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002373 """
2374 try:
GlennRCed771242016-01-13 17:02:47 -08002375 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2376 checkedStates = []
2377 statesCount = [0, 0, 0, 0]
2378 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002379 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002380 if rawFlows:
2381 # if we didn't get flows or flows function return None, we should return
2382 # main.Flase
2383 checkedStates.append( json.loads( rawFlows ) )
2384 else:
2385 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002386 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002387 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002388 try:
2389 statesCount[i] += int( c.get( "flowCount" ) )
2390 except TypeError:
2391 main.log.exception( "Json object not as expected" )
2392 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002393
GlennRCed771242016-01-13 17:02:47 -08002394 # We want to count PENDING_ADD if isPENDING is true
2395 if isPENDING:
2396 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2397 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002398 else:
GlennRCed771242016-01-13 17:02:47 -08002399 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2400 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002401 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002402 except ( TypeError, ValueError ):
2403 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002404 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002405
YPZhang240842b2016-05-17 12:00:50 -07002406 except AssertionError:
2407 main.log.exception( "" )
2408 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002409 except pexpect.EOF:
2410 main.log.error( self.name + ": EOF exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
2412 main.cleanup()
2413 main.exit()
2414 except Exception:
2415 main.log.exception( self.name + ": Uncaught exception!" )
2416 main.cleanup()
2417 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002418 except pexpect.TIMEOUT:
2419 main.log.error( self.name + ": ONOS timeout" )
2420 return None
2421
kelvin-onlab4df89f22015-04-13 18:10:23 -07002422
GlennRCed771242016-01-13 17:02:47 -08002423 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002424 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002425 """
andrewonlab87852b02014-11-19 18:44:19 -05002426 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002427 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002428 a specific point-to-point intent definition
2429 Required:
GlennRCed771242016-01-13 17:02:47 -08002430 * ingress: specify source dpid
2431 * egress: specify destination dpid
2432 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002433 Optional:
GlennRCed771242016-01-13 17:02:47 -08002434 * offset: the keyOffset is where the next batch of intents
2435 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002436 * noExit: If set to True, TestON will not exit if any error when issus command
2437 * getResponse: If set to True, function will return ONOS response.
2438
GlennRCed771242016-01-13 17:02:47 -08002439 Returns: If failed to push test intents, it will returen None,
2440 if successful, return true.
2441 Timeout expection will return None,
2442 TypeError will return false
2443 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002444 """
andrewonlab87852b02014-11-19 18:44:19 -05002445 try:
GlennRCed771242016-01-13 17:02:47 -08002446 if background:
2447 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002448 else:
GlennRCed771242016-01-13 17:02:47 -08002449 back = ""
2450 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002451 ingress,
2452 egress,
2453 batchSize,
2454 offset,
2455 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002456 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002457 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002458 main.log.info( response )
2459 if response == None:
2460 return None
2461
YPZhangb34b7e12016-06-14 14:28:19 -07002462 if getResponse:
2463 return response
2464
GlennRCed771242016-01-13 17:02:47 -08002465 # TODO: We should handle if there is failure in installation
2466 return main.TRUE
2467
Jon Hallc6793552016-01-19 14:18:37 -08002468 except AssertionError:
2469 main.log.exception( "" )
2470 return None
GlennRCed771242016-01-13 17:02:47 -08002471 except pexpect.TIMEOUT:
2472 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002473 return None
andrewonlab87852b02014-11-19 18:44:19 -05002474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002475 main.log.error( self.name + ": EOF exception found" )
2476 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002477 main.cleanup()
2478 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002479 except TypeError:
2480 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002481 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002482 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002483 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002484 main.cleanup()
2485 main.exit()
2486
YPZhangebf9eb52016-05-12 15:20:24 -07002487 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002488 """
2489 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002490 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002491 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002492 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002493 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002494 """
YPZhange3109a72016-02-02 11:25:37 -08002495
YPZhangb5d3f832016-01-23 22:54:26 -08002496 try:
YPZhange3109a72016-02-02 11:25:37 -08002497 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002498 cmd = "flows -c added"
2499 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2500 if rawFlows:
2501 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002502 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002503 for l in rawFlows:
2504 totalFlows += int(l.split("Count=")[1])
2505 else:
2506 main.log.error("Response not as expected!")
2507 return None
2508 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002509
You Wangd3cb2ce2016-05-16 14:01:24 -07002510 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002511 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002512 return None
2513 except pexpect.EOF:
2514 main.log.error( self.name + ": EOF exception found" )
2515 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002516 if not noExit:
2517 main.cleanup()
2518 main.exit()
2519 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002520 except Exception:
2521 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002522 if not noExit:
2523 main.cleanup()
2524 main.exit()
2525 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002526 except pexpect.TIMEOUT:
2527 main.log.error( self.name + ": ONOS timeout" )
2528 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002529
YPZhang14a4aa92016-07-15 13:37:15 -07002530 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002531 """
2532 Description:
2533 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002534 Optional:
2535 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002536 Return:
2537 The number of intents
2538 """
2539 try:
2540 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002541 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002542 if response == None:
2543 return -1
2544 response = json.loads( response )
2545 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002546 except ( TypeError, ValueError ):
2547 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002548 return None
2549 except pexpect.EOF:
2550 main.log.error( self.name + ": EOF exception found" )
2551 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002552 if noExit:
2553 return -1
2554 else:
2555 main.cleanup()
2556 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002557 except Exception:
2558 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002559 if noExit:
2560 return -1
2561 else:
2562 main.cleanup()
2563 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002564
kelvin-onlabd3b64892015-01-20 13:26:24 -08002565 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002566 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002567 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002568 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002570 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002571 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002572 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002573 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002574 cmdStr += " -j"
2575 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002576 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002577 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002578 except AssertionError:
2579 main.log.exception( "" )
2580 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002581 except TypeError:
2582 main.log.exception( self.name + ": Object not as expected" )
2583 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002584 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002585 main.log.error( self.name + ": EOF exception found" )
2586 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002587 main.cleanup()
2588 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002589 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002590 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002591 main.cleanup()
2592 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002593
kelvin-onlabd3b64892015-01-20 13:26:24 -08002594 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002595 """
2596 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002597 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002599 """
andrewonlab867212a2014-10-22 20:13:38 -04002600 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002601 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002602 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002603 cmdStr += " -j"
2604 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002605 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002606 if handle:
2607 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002608 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002609 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002610 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002611 else:
2612 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002613 except AssertionError:
2614 main.log.exception( "" )
2615 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002616 except TypeError:
2617 main.log.exception( self.name + ": Object not as expected" )
2618 return None
andrewonlab867212a2014-10-22 20:13:38 -04002619 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002620 main.log.error( self.name + ": EOF exception found" )
2621 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002622 main.cleanup()
2623 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002624 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002625 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002626 main.cleanup()
2627 main.exit()
2628
kelvin8ec71442015-01-15 16:57:00 -08002629 # Wrapper functions ****************
2630 # Wrapper functions use existing driver
2631 # functions and extends their use case.
2632 # For example, we may use the output of
2633 # a normal driver function, and parse it
2634 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002635
kelvin-onlabd3b64892015-01-20 13:26:24 -08002636 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002637 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002638 Description:
2639 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002640 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002641 try:
kelvin8ec71442015-01-15 16:57:00 -08002642 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002643 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002645
kelvin8ec71442015-01-15 16:57:00 -08002646 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002647 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2648 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002649 match = re.search('id=0x([\da-f]+),', intents)
2650 if match:
2651 tmpId = match.group()[3:-1]
2652 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002654
Jon Halld4d4b372015-01-28 16:02:41 -08002655 except TypeError:
2656 main.log.exception( self.name + ": Object not as expected" )
2657 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002659 main.log.error( self.name + ": EOF exception found" )
2660 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002661 main.cleanup()
2662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002663 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002664 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002665 main.cleanup()
2666 main.exit()
2667
You Wang3c276252016-09-21 15:21:36 -07002668 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002669 """
2670 Determine the number of flow rules for the given device id that are
2671 in the added state
You Wang3c276252016-09-21 15:21:36 -07002672 Params:
2673 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002674 """
2675 try:
You Wang3c276252016-09-21 15:21:36 -07002676 if core:
2677 cmdStr = "flows any " + str( deviceId ) + " | " +\
2678 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2679 else:
2680 cmdStr = "flows any " + str( deviceId ) + " | " +\
2681 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002682 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002683 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002684 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002685 except AssertionError:
2686 main.log.exception( "" )
2687 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002688 except pexpect.EOF:
2689 main.log.error( self.name + ": EOF exception found" )
2690 main.log.error( self.name + ": " + self.handle.before )
2691 main.cleanup()
2692 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002693 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002694 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002695 main.cleanup()
2696 main.exit()
2697
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002699 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002700 Use 'devices' function to obtain list of all devices
2701 and parse the result to obtain a list of all device
2702 id's. Returns this list. Returns empty list if no
2703 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002704 List is ordered sequentially
2705
andrewonlab3e15ead2014-10-15 14:21:34 -04002706 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002707 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002708 the ids. By obtaining the list of device ids on the fly,
2709 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002710 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002711 try:
kelvin8ec71442015-01-15 16:57:00 -08002712 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002713 devicesStr = self.devices( jsonFormat=False )
2714 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002715
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002717 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 return idList
kelvin8ec71442015-01-15 16:57:00 -08002719
2720 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002722 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002724 # Split list further into arguments before and after string
2725 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002726 # append to idList
2727 for arg in tempList:
2728 idList.append( arg.split( "id=" )[ 1 ] )
2729 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002730
Jon Halld4d4b372015-01-28 16:02:41 -08002731 except TypeError:
2732 main.log.exception( self.name + ": Object not as expected" )
2733 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002734 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002735 main.log.error( self.name + ": EOF exception found" )
2736 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002737 main.cleanup()
2738 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002739 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002740 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002741 main.cleanup()
2742 main.exit()
2743
kelvin-onlabd3b64892015-01-20 13:26:24 -08002744 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002745 """
andrewonlab7c211572014-10-15 16:45:20 -04002746 Uses 'nodes' function to obtain list of all nodes
2747 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002748 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002749 Returns:
2750 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002751 """
andrewonlab7c211572014-10-15 16:45:20 -04002752 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002753 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002755 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002756 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002758 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002759 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002760 nodesJson = json.loads( nodesStr )
2761 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002763 except ( TypeError, ValueError ):
2764 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002765 return None
andrewonlab7c211572014-10-15 16:45:20 -04002766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002769 main.cleanup()
2770 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002771 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002772 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002773 main.cleanup()
2774 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002775
kelvin-onlabd3b64892015-01-20 13:26:24 -08002776 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002777 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002778 Return the first device from the devices api whose 'id' contains 'dpid'
2779 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002780 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002781 try:
kelvin8ec71442015-01-15 16:57:00 -08002782 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002783 return None
2784 else:
kelvin8ec71442015-01-15 16:57:00 -08002785 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002786 rawDevices = self.devices()
2787 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002788 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002790 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2791 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002792 return device
2793 return None
Jon Hallc6793552016-01-19 14:18:37 -08002794 except ( TypeError, ValueError ):
2795 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002796 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002797 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002798 main.log.error( self.name + ": EOF exception found" )
2799 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002800 main.cleanup()
2801 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002802 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002803 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002804 main.cleanup()
2805 main.exit()
2806
You Wang24139872016-05-03 11:48:47 -07002807 def getTopology( self, topologyOutput ):
2808 """
2809 Definition:
2810 Loads a json topology output
2811 Return:
2812 topology = current ONOS topology
2813 """
2814 import json
2815 try:
2816 # either onos:topology or 'topology' will work in CLI
2817 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002818 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002819 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002820 except ( TypeError, ValueError ):
2821 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2822 return None
You Wang24139872016-05-03 11:48:47 -07002823 except pexpect.EOF:
2824 main.log.error( self.name + ": EOF exception found" )
2825 main.log.error( self.name + ": " + self.handle.before )
2826 main.cleanup()
2827 main.exit()
2828 except Exception:
2829 main.log.exception( self.name + ": Uncaught exception!" )
2830 main.cleanup()
2831 main.exit()
2832
Flavio Castro82ee2f62016-06-07 15:04:12 -07002833 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002834 """
Jon Hallefbd9792015-03-05 16:11:36 -08002835 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002836 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002837 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002838
Flavio Castro82ee2f62016-06-07 15:04:12 -07002839 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002840 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002841 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002842 logLevel = level to log to.
2843 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002844
Jon Hallefbd9792015-03-05 16:11:36 -08002845 Returns: main.TRUE if the number of switches and links are correct,
2846 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002847 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002848 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002849 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002850 try:
You Wang13310252016-07-31 10:56:14 -07002851 summary = self.summary()
2852 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002853 except ( TypeError, ValueError ):
2854 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2855 return main.ERROR
2856 try:
2857 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002858 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002859 return main.ERROR
2860 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002861 # Is the number of switches is what we expected
2862 devices = topology.get( 'devices', False )
2863 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002864 nodes = summary.get( 'nodes', False )
2865 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002866 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002868 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002870 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2871 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002872 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002873 output = output + "The number of links and switches match "\
2874 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002875 result = main.TRUE
2876 else:
You Wang24139872016-05-03 11:48:47 -07002877 output = output + \
2878 "The number of links and switches does not match " + \
2879 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002880 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002881 output = output + "\n ONOS sees %i devices" % int( devices )
2882 output = output + " (%i expected) " % int( numoswitch )
2883 output = output + "and %i links " % int( links )
2884 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002885 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002886 output = output + "and %i controllers " % int( nodes )
2887 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002889 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002890 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002891 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002892 else:
You Wang24139872016-05-03 11:48:47 -07002893 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002894 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002895 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002896 main.log.error( self.name + ": EOF exception found" )
2897 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002898 main.cleanup()
2899 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002900 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002901 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002902 main.cleanup()
2903 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002904
kelvin-onlabd3b64892015-01-20 13:26:24 -08002905 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002906 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002907 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002908 deviceId must be the id of a device as seen in the onos devices command
2909 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002910 role must be either master, standby, or none
2911
Jon Halle3f39ff2015-01-13 11:50:53 -08002912 Returns:
2913 main.TRUE or main.FALSE based on argument verification and
2914 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002915 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002916 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002917 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002918 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002919 cmdStr = "device-role " +\
2920 str( deviceId ) + " " +\
2921 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002922 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002923 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002924 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002925 if re.search( "Error", handle ):
2926 # end color output to escape any colours
2927 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002928 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002929 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002930 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002931 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002932 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002933 main.log.error( "Invalid 'role' given to device_role(). " +
2934 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002935 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002936 except AssertionError:
2937 main.log.exception( "" )
2938 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002939 except TypeError:
2940 main.log.exception( self.name + ": Object not as expected" )
2941 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002943 main.log.error( self.name + ": EOF exception found" )
2944 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002945 main.cleanup()
2946 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002947 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002948 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002949 main.cleanup()
2950 main.exit()
2951
kelvin-onlabd3b64892015-01-20 13:26:24 -08002952 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002953 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002954 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002955 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002956 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002957 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002958 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002959 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002960 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002961 cmdStr += " -j"
2962 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002963 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002964 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002965 except AssertionError:
2966 main.log.exception( "" )
2967 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002968 except TypeError:
2969 main.log.exception( self.name + ": Object not as expected" )
2970 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002971 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002972 main.log.error( self.name + ": EOF exception found" )
2973 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002974 main.cleanup()
2975 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002976 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002977 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002978 main.cleanup()
2979 main.exit()
2980
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002982 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002983 CLI command to get the current leader for the Election test application
2984 NOTE: Requires installation of the onos-app-election feature
2985 Returns: Node IP of the leader if one exists
2986 None if none exists
2987 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002988 """
Jon Hall94fd0472014-12-08 11:52:42 -08002989 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002990 cmdStr = "election-test-leader"
2991 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002992 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002993 # Leader
2994 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002995 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002996 nodeSearch = re.search( leaderPattern, response )
2997 if nodeSearch:
2998 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002999 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003000 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003001 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003002 # no leader
3003 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003004 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003005 nullSearch = re.search( nullPattern, response )
3006 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003007 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003009 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003010 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003011 main.log.error( "Error in electionTestLeader on " + self.name +
3012 ": " + "unexpected response" )
3013 main.log.error( repr( response ) )
3014 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003015 except AssertionError:
3016 main.log.exception( "" )
3017 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003018 except TypeError:
3019 main.log.exception( self.name + ": Object not as expected" )
3020 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003021 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003022 main.log.error( self.name + ": EOF exception found" )
3023 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003024 main.cleanup()
3025 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003026 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003027 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003028 main.cleanup()
3029 main.exit()
3030
kelvin-onlabd3b64892015-01-20 13:26:24 -08003031 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003033 CLI command to run for leadership of the Election test application.
3034 NOTE: Requires installation of the onos-app-election feature
3035 Returns: Main.TRUE on success
3036 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 """
Jon Hall94fd0472014-12-08 11:52:42 -08003038 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003039 cmdStr = "election-test-run"
3040 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003041 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003043 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003044 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003045 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003046 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003047 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003048 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003049 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003050 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003051 main.log.error( "Error in electionTestRun on " + self.name +
3052 ": " + "unexpected response" )
3053 main.log.error( repr( response ) )
3054 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003055 except AssertionError:
3056 main.log.exception( "" )
3057 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003058 except TypeError:
3059 main.log.exception( self.name + ": Object not as expected" )
3060 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003061 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003062 main.log.error( self.name + ": EOF exception found" )
3063 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003064 main.cleanup()
3065 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003066 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003067 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003068 main.cleanup()
3069 main.exit()
3070
kelvin-onlabd3b64892015-01-20 13:26:24 -08003071 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003072 """
Jon Hall94fd0472014-12-08 11:52:42 -08003073 * CLI command to withdraw the local node from leadership election for
3074 * the Election test application.
3075 #NOTE: Requires installation of the onos-app-election feature
3076 Returns: Main.TRUE on success
3077 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003078 """
Jon Hall94fd0472014-12-08 11:52:42 -08003079 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003080 cmdStr = "election-test-withdraw"
3081 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003082 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003083 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003084 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003085 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003086 if re.search( successPattern, response ):
3087 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003088 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003089 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003090 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003091 main.log.error( "Error in electionTestWithdraw on " +
3092 self.name + ": " + "unexpected response" )
3093 main.log.error( repr( response ) )
3094 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003095 except AssertionError:
3096 main.log.exception( "" )
3097 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003098 except TypeError:
3099 main.log.exception( self.name + ": Object not as expected" )
3100 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003104 main.cleanup()
3105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003106 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003107 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003108 main.cleanup()
3109 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003110
kelvin8ec71442015-01-15 16:57:00 -08003111 def getDevicePortsEnabledCount( self, dpid ):
3112 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003113 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003114 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003115 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003117 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3118 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003119 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003120 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003121 if re.search( "No such device", output ):
3122 main.log.error( "Error in getting ports" )
3123 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003124 return output
Jon Hallc6793552016-01-19 14:18:37 -08003125 except AssertionError:
3126 main.log.exception( "" )
3127 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003128 except TypeError:
3129 main.log.exception( self.name + ": Object not as expected" )
3130 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003132 main.log.error( self.name + ": EOF exception found" )
3133 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003134 main.cleanup()
3135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003137 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003138 main.cleanup()
3139 main.exit()
3140
kelvin8ec71442015-01-15 16:57:00 -08003141 def getDeviceLinksActiveCount( self, dpid ):
3142 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003144 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003145 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003146 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003147 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3148 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003149 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003150 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003151 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003152 main.log.error( "Error in getting ports " )
3153 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003154 return output
Jon Hallc6793552016-01-19 14:18:37 -08003155 except AssertionError:
3156 main.log.exception( "" )
3157 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003158 except TypeError:
3159 main.log.exception( self.name + ": Object not as expected" )
3160 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003162 main.log.error( self.name + ": EOF exception found" )
3163 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164 main.cleanup()
3165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003167 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003168 main.cleanup()
3169 main.exit()
3170
kelvin8ec71442015-01-15 16:57:00 -08003171 def getAllIntentIds( self ):
3172 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003173 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003174 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003175 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 cmdStr = "onos:intents | grep id="
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( "Error", output ):
3181 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!" )
3197 main.cleanup()
3198 main.exit()
3199
Jon Hall73509952015-02-24 16:42:56 -08003200 def intentSummary( self ):
3201 """
Jon Hallefbd9792015-03-05 16:11:36 -08003202 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003203 """
3204 try:
3205 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003206 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003207 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003208 states.append( intent.get( 'state', None ) )
3209 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003210 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003211 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003212 except ( TypeError, ValueError ):
3213 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003214 return None
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
3218 main.cleanup()
3219 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003220 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003221 main.log.exception( self.name + ": Uncaught exception!" )
3222 main.cleanup()
3223 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003224
Jon Hall61282e32015-03-19 11:34:11 -07003225 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003226 """
3227 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003228 Optional argument:
3229 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003230 """
Jon Hall63604932015-02-26 17:09:50 -08003231 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003232 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003233 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003234 cmdStr += " -j"
3235 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003236 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003237 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003238 return output
Jon Hallc6793552016-01-19 14:18:37 -08003239 except AssertionError:
3240 main.log.exception( "" )
3241 return None
Jon Hall63604932015-02-26 17:09:50 -08003242 except TypeError:
3243 main.log.exception( self.name + ": Object not as expected" )
3244 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003245 except pexpect.EOF:
3246 main.log.error( self.name + ": EOF exception found" )
3247 main.log.error( self.name + ": " + self.handle.before )
3248 main.cleanup()
3249 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003250 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003251 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003252 main.cleanup()
3253 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003254
acsmarsa4a4d1e2015-07-10 16:01:24 -07003255 def leaderCandidates( self, jsonFormat=True ):
3256 """
3257 Returns the output of the leaders -c command.
3258 Optional argument:
3259 * jsonFormat - boolean indicating if you want output in json
3260 """
3261 try:
3262 cmdStr = "onos:leaders -c"
3263 if jsonFormat:
3264 cmdStr += " -j"
3265 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003266 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003267 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003268 return output
Jon Hallc6793552016-01-19 14:18:37 -08003269 except AssertionError:
3270 main.log.exception( "" )
3271 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003272 except TypeError:
3273 main.log.exception( self.name + ": Object not as expected" )
3274 return None
3275 except pexpect.EOF:
3276 main.log.error( self.name + ": EOF exception found" )
3277 main.log.error( self.name + ": " + self.handle.before )
3278 main.cleanup()
3279 main.exit()
3280 except Exception:
3281 main.log.exception( self.name + ": Uncaught exception!" )
3282 main.cleanup()
3283 main.exit()
3284
Jon Hallc6793552016-01-19 14:18:37 -08003285 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003286 """
3287 Returns a list in format [leader,candidate1,candidate2,...] for a given
3288 topic parameter and an empty list if the topic doesn't exist
3289 If no leader is elected leader in the returned list will be "none"
3290 Returns None if there is a type error processing the json object
3291 """
3292 try:
Jon Hall6e709752016-02-01 13:38:46 -08003293 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003294 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003295 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003296 assert "Command not found:" not in rawOutput, rawOutput
3297 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298 results = []
3299 for dict in output:
3300 if dict["topic"] == topic:
3301 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003302 candidates = re.split( ", ", dict["candidates"][1:-1] )
3303 results.append( leader )
3304 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003305 return results
Jon Hallc6793552016-01-19 14:18:37 -08003306 except AssertionError:
3307 main.log.exception( "" )
3308 return None
3309 except ( TypeError, ValueError ):
3310 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003311 return None
3312 except pexpect.EOF:
3313 main.log.error( self.name + ": EOF exception found" )
3314 main.log.error( self.name + ": " + self.handle.before )
3315 main.cleanup()
3316 main.exit()
3317 except Exception:
3318 main.log.exception( self.name + ": Uncaught exception!" )
3319 main.cleanup()
3320 main.exit()
3321
Jon Hall61282e32015-03-19 11:34:11 -07003322 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003323 """
3324 Returns the output of the intent Pending map.
3325 """
Jon Hall63604932015-02-26 17:09:50 -08003326 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003327 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003328 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003329 cmdStr += " -j"
3330 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003331 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003332 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003333 return output
Jon Hallc6793552016-01-19 14:18:37 -08003334 except AssertionError:
3335 main.log.exception( "" )
3336 return None
Jon Hall63604932015-02-26 17:09:50 -08003337 except TypeError:
3338 main.log.exception( self.name + ": Object not as expected" )
3339 return None
3340 except pexpect.EOF:
3341 main.log.error( self.name + ": EOF exception found" )
3342 main.log.error( self.name + ": " + self.handle.before )
3343 main.cleanup()
3344 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003345 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003346 main.log.exception( self.name + ": Uncaught exception!" )
3347 main.cleanup()
3348 main.exit()
3349
Jon Hall2c8959e2016-12-16 12:17:34 -08003350 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003351 """
3352 Returns the output of the raft partitions command for ONOS.
3353 """
Jon Hall61282e32015-03-19 11:34:11 -07003354 # Sample JSON
3355 # {
3356 # "leader": "tcp://10.128.30.11:7238",
3357 # "members": [
3358 # "tcp://10.128.30.11:7238",
3359 # "tcp://10.128.30.17:7238",
3360 # "tcp://10.128.30.13:7238",
3361 # ],
3362 # "name": "p1",
3363 # "term": 3
3364 # },
Jon Hall63604932015-02-26 17:09:50 -08003365 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003366 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003367 if candidates:
3368 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003369 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003370 cmdStr += " -j"
3371 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003372 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003373 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003374 return output
Jon Hallc6793552016-01-19 14:18:37 -08003375 except AssertionError:
3376 main.log.exception( "" )
3377 return None
Jon Hall63604932015-02-26 17:09:50 -08003378 except TypeError:
3379 main.log.exception( self.name + ": Object not as expected" )
3380 return None
3381 except pexpect.EOF:
3382 main.log.error( self.name + ": EOF exception found" )
3383 main.log.error( self.name + ": " + self.handle.before )
3384 main.cleanup()
3385 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003386 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003387 main.log.exception( self.name + ": Uncaught exception!" )
3388 main.cleanup()
3389 main.exit()
3390
Jon Halle9f909e2016-09-23 10:43:12 -07003391 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003392 """
3393 Returns the output of the apps command for ONOS. This command lists
3394 information about installed ONOS applications
3395 """
3396 # Sample JSON object
3397 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3398 # "description":"ONOS OpenFlow protocol southbound providers",
3399 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3400 # "features":"[onos-openflow]","state":"ACTIVE"}]
3401 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003402 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003403 if summary:
3404 cmdStr += " -s"
3405 if active:
3406 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003407 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003408 cmdStr += " -j"
3409 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003410 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003411 assert "Command not found:" not in output, output
3412 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003413 return output
Jon Hallbe379602015-03-24 13:39:32 -07003414 # FIXME: look at specific exceptions/Errors
3415 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003416 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003417 return None
3418 except TypeError:
3419 main.log.exception( self.name + ": Object not as expected" )
3420 return None
3421 except pexpect.EOF:
3422 main.log.error( self.name + ": EOF exception found" )
3423 main.log.error( self.name + ": " + self.handle.before )
3424 main.cleanup()
3425 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003426 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003427 main.log.exception( self.name + ": Uncaught exception!" )
3428 main.cleanup()
3429 main.exit()
3430
Jon Hall146f1522015-03-24 15:33:24 -07003431 def appStatus( self, appName ):
3432 """
3433 Uses the onos:apps cli command to return the status of an application.
3434 Returns:
3435 "ACTIVE" - If app is installed and activated
3436 "INSTALLED" - If app is installed and deactivated
3437 "UNINSTALLED" - If app is not installed
3438 None - on error
3439 """
Jon Hall146f1522015-03-24 15:33:24 -07003440 try:
3441 if not isinstance( appName, types.StringType ):
3442 main.log.error( self.name + ".appStatus(): appName must be" +
3443 " a string" )
3444 return None
3445 output = self.apps( jsonFormat=True )
3446 appsJson = json.loads( output )
3447 state = None
3448 for app in appsJson:
3449 if appName == app.get('name'):
3450 state = app.get('state')
3451 break
3452 if state == "ACTIVE" or state == "INSTALLED":
3453 return state
3454 elif state is None:
3455 return "UNINSTALLED"
3456 elif state:
3457 main.log.error( "Unexpected state from 'onos:apps': " +
3458 str( state ) )
3459 return state
Jon Hallc6793552016-01-19 14:18:37 -08003460 except ( TypeError, ValueError ):
3461 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003462 return None
3463 except pexpect.EOF:
3464 main.log.error( self.name + ": EOF exception found" )
3465 main.log.error( self.name + ": " + self.handle.before )
3466 main.cleanup()
3467 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003468 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003469 main.log.exception( self.name + ": Uncaught exception!" )
3470 main.cleanup()
3471 main.exit()
3472
Jon Hallbe379602015-03-24 13:39:32 -07003473 def app( self, appName, option ):
3474 """
3475 Interacts with the app command for ONOS. This command manages
3476 application inventory.
3477 """
Jon Hallbe379602015-03-24 13:39:32 -07003478 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003479 # Validate argument types
3480 valid = True
3481 if not isinstance( appName, types.StringType ):
3482 main.log.error( self.name + ".app(): appName must be a " +
3483 "string" )
3484 valid = False
3485 if not isinstance( option, types.StringType ):
3486 main.log.error( self.name + ".app(): option must be a string" )
3487 valid = False
3488 if not valid:
3489 return main.FALSE
3490 # Validate Option
3491 option = option.lower()
3492 # NOTE: Install may become a valid option
3493 if option == "activate":
3494 pass
3495 elif option == "deactivate":
3496 pass
3497 elif option == "uninstall":
3498 pass
3499 else:
3500 # Invalid option
3501 main.log.error( "The ONOS app command argument only takes " +
3502 "the values: (activate|deactivate|uninstall)" +
3503 "; was given '" + option + "'")
3504 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003505 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003506 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003507 if "Error executing command" in output:
3508 main.log.error( "Error in processing onos:app command: " +
3509 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003510 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003511 elif "No such application" in output:
3512 main.log.error( "The application '" + appName +
3513 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003514 return main.FALSE
3515 elif "Command not found:" in output:
3516 main.log.error( "Error in processing onos:app command: " +
3517 str( output ) )
3518 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003519 elif "Unsupported command:" in output:
3520 main.log.error( "Incorrect command given to 'app': " +
3521 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003522 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003523 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003524 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003525 return main.TRUE
3526 except TypeError:
3527 main.log.exception( self.name + ": Object not as expected" )
3528 return main.ERROR
3529 except pexpect.EOF:
3530 main.log.error( self.name + ": EOF exception found" )
3531 main.log.error( self.name + ": " + self.handle.before )
3532 main.cleanup()
3533 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003534 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003535 main.log.exception( self.name + ": Uncaught exception!" )
3536 main.cleanup()
3537 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003538
Jon Hallbd16b922015-03-26 17:53:15 -07003539 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003540 """
3541 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003542 appName is the hierarchical app name, not the feature name
3543 If check is True, method will check the status of the app after the
3544 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003545 Returns main.TRUE if the command was successfully sent
3546 main.FALSE if the cli responded with an error or given
3547 incorrect input
3548 """
3549 try:
3550 if not isinstance( appName, types.StringType ):
3551 main.log.error( self.name + ".activateApp(): appName must be" +
3552 " a string" )
3553 return main.FALSE
3554 status = self.appStatus( appName )
3555 if status == "INSTALLED":
3556 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003557 if check and response == main.TRUE:
3558 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003559 status = self.appStatus( appName )
3560 if status == "ACTIVE":
3561 return main.TRUE
3562 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003563 main.log.debug( "The state of application " +
3564 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003565 time.sleep( 1 )
3566 return main.FALSE
3567 else: # not 'check' or command didn't succeed
3568 return response
Jon Hall146f1522015-03-24 15:33:24 -07003569 elif status == "ACTIVE":
3570 return main.TRUE
3571 elif status == "UNINSTALLED":
3572 main.log.error( self.name + ": Tried to activate the " +
3573 "application '" + appName + "' which is not " +
3574 "installed." )
3575 else:
3576 main.log.error( "Unexpected return value from appStatus: " +
3577 str( status ) )
3578 return main.ERROR
3579 except TypeError:
3580 main.log.exception( self.name + ": Object not as expected" )
3581 return main.ERROR
3582 except pexpect.EOF:
3583 main.log.error( self.name + ": EOF exception found" )
3584 main.log.error( self.name + ": " + self.handle.before )
3585 main.cleanup()
3586 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003587 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003588 main.log.exception( self.name + ": Uncaught exception!" )
3589 main.cleanup()
3590 main.exit()
3591
Jon Hallbd16b922015-03-26 17:53:15 -07003592 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003593 """
3594 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003595 appName is the hierarchical app name, not the feature name
3596 If check is True, method will check the status of the app after the
3597 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003598 Returns main.TRUE if the command was successfully sent
3599 main.FALSE if the cli responded with an error or given
3600 incorrect input
3601 """
3602 try:
3603 if not isinstance( appName, types.StringType ):
3604 main.log.error( self.name + ".deactivateApp(): appName must " +
3605 "be a string" )
3606 return main.FALSE
3607 status = self.appStatus( appName )
3608 if status == "INSTALLED":
3609 return main.TRUE
3610 elif status == "ACTIVE":
3611 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003612 if check and response == main.TRUE:
3613 for i in range(10): # try 10 times then give up
3614 status = self.appStatus( appName )
3615 if status == "INSTALLED":
3616 return main.TRUE
3617 else:
3618 time.sleep( 1 )
3619 return main.FALSE
3620 else: # not check or command didn't succeed
3621 return response
Jon Hall146f1522015-03-24 15:33:24 -07003622 elif status == "UNINSTALLED":
3623 main.log.warn( self.name + ": Tried to deactivate the " +
3624 "application '" + appName + "' which is not " +
3625 "installed." )
3626 return main.TRUE
3627 else:
3628 main.log.error( "Unexpected return value from appStatus: " +
3629 str( status ) )
3630 return main.ERROR
3631 except TypeError:
3632 main.log.exception( self.name + ": Object not as expected" )
3633 return main.ERROR
3634 except pexpect.EOF:
3635 main.log.error( self.name + ": EOF exception found" )
3636 main.log.error( self.name + ": " + self.handle.before )
3637 main.cleanup()
3638 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003639 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003640 main.log.exception( self.name + ": Uncaught exception!" )
3641 main.cleanup()
3642 main.exit()
3643
Jon Hallbd16b922015-03-26 17:53:15 -07003644 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003645 """
3646 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003647 appName is the hierarchical app name, not the feature name
3648 If check is True, method will check the status of the app after the
3649 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003650 Returns main.TRUE if the command was successfully sent
3651 main.FALSE if the cli responded with an error or given
3652 incorrect input
3653 """
3654 # TODO: check with Thomas about the state machine for apps
3655 try:
3656 if not isinstance( appName, types.StringType ):
3657 main.log.error( self.name + ".uninstallApp(): appName must " +
3658 "be a string" )
3659 return main.FALSE
3660 status = self.appStatus( appName )
3661 if status == "INSTALLED":
3662 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003663 if check and response == main.TRUE:
3664 for i in range(10): # try 10 times then give up
3665 status = self.appStatus( appName )
3666 if status == "UNINSTALLED":
3667 return main.TRUE
3668 else:
3669 time.sleep( 1 )
3670 return main.FALSE
3671 else: # not check or command didn't succeed
3672 return response
Jon Hall146f1522015-03-24 15:33:24 -07003673 elif status == "ACTIVE":
3674 main.log.warn( self.name + ": Tried to uninstall the " +
3675 "application '" + appName + "' which is " +
3676 "currently active." )
3677 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003678 if check and response == main.TRUE:
3679 for i in range(10): # try 10 times then give up
3680 status = self.appStatus( appName )
3681 if status == "UNINSTALLED":
3682 return main.TRUE
3683 else:
3684 time.sleep( 1 )
3685 return main.FALSE
3686 else: # not check or command didn't succeed
3687 return response
Jon Hall146f1522015-03-24 15:33:24 -07003688 elif status == "UNINSTALLED":
3689 return main.TRUE
3690 else:
3691 main.log.error( "Unexpected return value from appStatus: " +
3692 str( status ) )
3693 return main.ERROR
3694 except TypeError:
3695 main.log.exception( self.name + ": Object not as expected" )
3696 return main.ERROR
3697 except pexpect.EOF:
3698 main.log.error( self.name + ": EOF exception found" )
3699 main.log.error( self.name + ": " + self.handle.before )
3700 main.cleanup()
3701 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003702 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003703 main.log.exception( self.name + ": Uncaught exception!" )
3704 main.cleanup()
3705 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003706
3707 def appIDs( self, jsonFormat=True ):
3708 """
3709 Show the mappings between app id and app names given by the 'app-ids'
3710 cli command
3711 """
3712 try:
3713 cmdStr = "app-ids"
3714 if jsonFormat:
3715 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003716 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003717 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003718 assert "Command not found:" not in output, output
3719 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003720 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003721 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003722 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003723 return None
3724 except TypeError:
3725 main.log.exception( self.name + ": Object not as expected" )
3726 return None
3727 except pexpect.EOF:
3728 main.log.error( self.name + ": EOF exception found" )
3729 main.log.error( self.name + ": " + self.handle.before )
3730 main.cleanup()
3731 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003732 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003733 main.log.exception( self.name + ": Uncaught exception!" )
3734 main.cleanup()
3735 main.exit()
3736
3737 def appToIDCheck( self ):
3738 """
3739 This method will check that each application's ID listed in 'apps' is
3740 the same as the ID listed in 'app-ids'. The check will also check that
3741 there are no duplicate IDs issued. Note that an app ID should be
3742 a globaly unique numerical identifier for app/app-like features. Once
3743 an ID is registered, the ID is never freed up so that if an app is
3744 reinstalled it will have the same ID.
3745
3746 Returns: main.TRUE if the check passes and
3747 main.FALSE if the check fails or
3748 main.ERROR if there is some error in processing the test
3749 """
3750 try:
Jon Hall390696c2015-05-05 17:13:41 -07003751 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003752 rawJson = self.appIDs( jsonFormat=True )
3753 if rawJson:
3754 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003755 else:
Jon Hallc6793552016-01-19 14:18:37 -08003756 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003757 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003758 rawJson = self.apps( jsonFormat=True )
3759 if rawJson:
3760 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003761 else:
Jon Hallc6793552016-01-19 14:18:37 -08003762 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003763 bail = True
3764 if bail:
3765 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003766 result = main.TRUE
3767 for app in apps:
3768 appID = app.get( 'id' )
3769 if appID is None:
3770 main.log.error( "Error parsing app: " + str( app ) )
3771 result = main.FALSE
3772 appName = app.get( 'name' )
3773 if appName is None:
3774 main.log.error( "Error parsing app: " + str( app ) )
3775 result = main.FALSE
3776 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003777 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003778 # main.log.debug( "Comparing " + str( app ) + " to " +
3779 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003780 if not current: # if ids doesn't have this id
3781 result = main.FALSE
3782 main.log.error( "'app-ids' does not have the ID for " +
3783 str( appName ) + " that apps does." )
3784 elif len( current ) > 1:
3785 # there is more than one app with this ID
3786 result = main.FALSE
3787 # We will log this later in the method
3788 elif not current[0][ 'name' ] == appName:
3789 currentName = current[0][ 'name' ]
3790 result = main.FALSE
3791 main.log.error( "'app-ids' has " + str( currentName ) +
3792 " registered under id:" + str( appID ) +
3793 " but 'apps' has " + str( appName ) )
3794 else:
3795 pass # id and name match!
3796 # now make sure that app-ids has no duplicates
3797 idsList = []
3798 namesList = []
3799 for item in ids:
3800 idsList.append( item[ 'id' ] )
3801 namesList.append( item[ 'name' ] )
3802 if len( idsList ) != len( set( idsList ) ) or\
3803 len( namesList ) != len( set( namesList ) ):
3804 main.log.error( "'app-ids' has some duplicate entries: \n"
3805 + json.dumps( ids,
3806 sort_keys=True,
3807 indent=4,
3808 separators=( ',', ': ' ) ) )
3809 result = main.FALSE
3810 return result
Jon Hallc6793552016-01-19 14:18:37 -08003811 except ( TypeError, ValueError ):
3812 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003813 return main.ERROR
3814 except pexpect.EOF:
3815 main.log.error( self.name + ": EOF exception found" )
3816 main.log.error( self.name + ": " + self.handle.before )
3817 main.cleanup()
3818 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003819 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003820 main.log.exception( self.name + ": Uncaught exception!" )
3821 main.cleanup()
3822 main.exit()
3823
Jon Hallfb760a02015-04-13 15:35:03 -07003824 def getCfg( self, component=None, propName=None, short=False,
3825 jsonFormat=True ):
3826 """
3827 Get configuration settings from onos cli
3828 Optional arguments:
3829 component - Optionally only list configurations for a specific
3830 component. If None, all components with configurations
3831 are displayed. Case Sensitive string.
3832 propName - If component is specified, propName option will show
3833 only this specific configuration from that component.
3834 Case Sensitive string.
3835 jsonFormat - Returns output as json. Note that this will override
3836 the short option
3837 short - Short, less verbose, version of configurations.
3838 This is overridden by the json option
3839 returns:
3840 Output from cli as a string or None on error
3841 """
3842 try:
3843 baseStr = "cfg"
3844 cmdStr = " get"
3845 componentStr = ""
3846 if component:
3847 componentStr += " " + component
3848 if propName:
3849 componentStr += " " + propName
3850 if jsonFormat:
3851 baseStr += " -j"
3852 elif short:
3853 baseStr += " -s"
3854 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003855 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003856 assert "Command not found:" not in output, output
3857 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003858 return output
3859 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003860 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003861 return None
3862 except TypeError:
3863 main.log.exception( self.name + ": Object not as expected" )
3864 return None
3865 except pexpect.EOF:
3866 main.log.error( self.name + ": EOF exception found" )
3867 main.log.error( self.name + ": " + self.handle.before )
3868 main.cleanup()
3869 main.exit()
3870 except Exception:
3871 main.log.exception( self.name + ": Uncaught exception!" )
3872 main.cleanup()
3873 main.exit()
3874
3875 def setCfg( self, component, propName, value=None, check=True ):
3876 """
3877 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003878 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003879 component - The case sensitive name of the component whose
3880 property is to be set
3881 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003882 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003883 value - The value to set the property to. If None, will unset the
3884 property and revert it to it's default value(if applicable)
3885 check - Boolean, Check whether the option was successfully set this
3886 only applies when a value is given.
3887 returns:
3888 main.TRUE on success or main.FALSE on failure. If check is False,
3889 will return main.TRUE unless there is an error
3890 """
3891 try:
3892 baseStr = "cfg"
3893 cmdStr = " set " + str( component ) + " " + str( propName )
3894 if value is not None:
3895 cmdStr += " " + str( value )
3896 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003897 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003898 assert "Command not found:" not in output, output
3899 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003900 if value and check:
3901 results = self.getCfg( component=str( component ),
3902 propName=str( propName ),
3903 jsonFormat=True )
3904 # Check if current value is what we just set
3905 try:
3906 jsonOutput = json.loads( results )
3907 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003908 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003909 main.log.exception( "Error parsing cfg output" )
3910 main.log.error( "output:" + repr( results ) )
3911 return main.FALSE
3912 if current == str( value ):
3913 return main.TRUE
3914 return main.FALSE
3915 return main.TRUE
3916 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003917 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003918 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003919 except ( TypeError, ValueError ):
3920 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003921 return main.FALSE
3922 except pexpect.EOF:
3923 main.log.error( self.name + ": EOF exception found" )
3924 main.log.error( self.name + ": " + self.handle.before )
3925 main.cleanup()
3926 main.exit()
3927 except Exception:
3928 main.log.exception( self.name + ": Uncaught exception!" )
3929 main.cleanup()
3930 main.exit()
3931
Jon Hall390696c2015-05-05 17:13:41 -07003932 def setTestAdd( self, setName, values ):
3933 """
3934 CLI command to add elements to a distributed set.
3935 Arguments:
3936 setName - The name of the set to add to.
3937 values - The value(s) to add to the set, space seperated.
3938 Example usages:
3939 setTestAdd( "set1", "a b c" )
3940 setTestAdd( "set2", "1" )
3941 returns:
3942 main.TRUE on success OR
3943 main.FALSE if elements were already in the set OR
3944 main.ERROR on error
3945 """
3946 try:
3947 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3948 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003949 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003950 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003951 try:
3952 # TODO: Maybe make this less hardcoded
3953 # ConsistentMap Exceptions
3954 assert "org.onosproject.store.service" not in output
3955 # Node not leader
3956 assert "java.lang.IllegalStateException" not in output
3957 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003958 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003959 "command: " + str( output ) )
3960 retryTime = 30 # Conservative time, given by Madan
3961 main.log.info( "Waiting " + str( retryTime ) +
3962 "seconds before retrying." )
3963 time.sleep( retryTime ) # Due to change in mastership
3964 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003965 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003966 assert "Error executing command" not in output
3967 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3968 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3969 main.log.info( self.name + ": " + output )
3970 if re.search( positiveMatch, output):
3971 return main.TRUE
3972 elif re.search( negativeMatch, output):
3973 return main.FALSE
3974 else:
3975 main.log.error( self.name + ": setTestAdd did not" +
3976 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003977 main.log.debug( self.name + " actual: " + repr( output ) )
3978 return main.ERROR
3979 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003980 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003981 return main.ERROR
3982 except TypeError:
3983 main.log.exception( self.name + ": Object not as expected" )
3984 return main.ERROR
3985 except pexpect.EOF:
3986 main.log.error( self.name + ": EOF exception found" )
3987 main.log.error( self.name + ": " + self.handle.before )
3988 main.cleanup()
3989 main.exit()
3990 except Exception:
3991 main.log.exception( self.name + ": Uncaught exception!" )
3992 main.cleanup()
3993 main.exit()
3994
3995 def setTestRemove( self, setName, values, clear=False, retain=False ):
3996 """
3997 CLI command to remove elements from a distributed set.
3998 Required arguments:
3999 setName - The name of the set to remove from.
4000 values - The value(s) to remove from the set, space seperated.
4001 Optional arguments:
4002 clear - Clear all elements from the set
4003 retain - Retain only the given values. (intersection of the
4004 original set and the given set)
4005 returns:
4006 main.TRUE on success OR
4007 main.FALSE if the set was not changed OR
4008 main.ERROR on error
4009 """
4010 try:
4011 cmdStr = "set-test-remove "
4012 if clear:
4013 cmdStr += "-c " + str( setName )
4014 elif retain:
4015 cmdStr += "-r " + str( setName ) + " " + str( values )
4016 else:
4017 cmdStr += str( setName ) + " " + str( values )
4018 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004019 try:
Jon Halla495f562016-05-16 18:03:26 -07004020 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004021 # TODO: Maybe make this less hardcoded
4022 # ConsistentMap Exceptions
4023 assert "org.onosproject.store.service" not in output
4024 # Node not leader
4025 assert "java.lang.IllegalStateException" not in output
4026 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004027 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004028 "command: " + str( output ) )
4029 retryTime = 30 # Conservative time, given by Madan
4030 main.log.info( "Waiting " + str( retryTime ) +
4031 "seconds before retrying." )
4032 time.sleep( retryTime ) # Due to change in mastership
4033 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004034 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004035 assert "Command not found:" not in output, output
4036 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004037 main.log.info( self.name + ": " + output )
4038 if clear:
4039 pattern = "Set " + str( setName ) + " cleared"
4040 if re.search( pattern, output ):
4041 return main.TRUE
4042 elif retain:
4043 positivePattern = str( setName ) + " was pruned to contain " +\
4044 "only elements of set \[(.*)\]"
4045 negativePattern = str( setName ) + " was not changed by " +\
4046 "retaining only elements of the set " +\
4047 "\[(.*)\]"
4048 if re.search( positivePattern, output ):
4049 return main.TRUE
4050 elif re.search( negativePattern, output ):
4051 return main.FALSE
4052 else:
4053 positivePattern = "\[(.*)\] was removed from the set " +\
4054 str( setName )
4055 if ( len( values.split() ) == 1 ):
4056 negativePattern = "\[(.*)\] was not in set " +\
4057 str( setName )
4058 else:
4059 negativePattern = "No element of \[(.*)\] was in set " +\
4060 str( setName )
4061 if re.search( positivePattern, output ):
4062 return main.TRUE
4063 elif re.search( negativePattern, output ):
4064 return main.FALSE
4065 main.log.error( self.name + ": setTestRemove did not" +
4066 " match expected output" )
4067 main.log.debug( self.name + " expected: " + pattern )
4068 main.log.debug( self.name + " actual: " + repr( output ) )
4069 return main.ERROR
4070 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004071 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004072 return main.ERROR
4073 except TypeError:
4074 main.log.exception( self.name + ": Object not as expected" )
4075 return main.ERROR
4076 except pexpect.EOF:
4077 main.log.error( self.name + ": EOF exception found" )
4078 main.log.error( self.name + ": " + self.handle.before )
4079 main.cleanup()
4080 main.exit()
4081 except Exception:
4082 main.log.exception( self.name + ": Uncaught exception!" )
4083 main.cleanup()
4084 main.exit()
4085
4086 def setTestGet( self, setName, values="" ):
4087 """
4088 CLI command to get the elements in a distributed set.
4089 Required arguments:
4090 setName - The name of the set to remove from.
4091 Optional arguments:
4092 values - The value(s) to check if in the set, space seperated.
4093 returns:
4094 main.ERROR on error OR
4095 A list of elements in the set if no optional arguments are
4096 supplied OR
4097 A tuple containing the list then:
4098 main.FALSE if the given values are not in the set OR
4099 main.TRUE if the given values are in the set OR
4100 """
4101 try:
4102 values = str( values ).strip()
4103 setName = str( setName ).strip()
4104 length = len( values.split() )
4105 containsCheck = None
4106 # Patterns to match
4107 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004108 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004109 containsTrue = "Set " + setName + " contains the value " + values
4110 containsFalse = "Set " + setName + " did not contain the value " +\
4111 values
4112 containsAllTrue = "Set " + setName + " contains the the subset " +\
4113 setPattern
4114 containsAllFalse = "Set " + setName + " did not contain the the" +\
4115 " subset " + setPattern
4116
4117 cmdStr = "set-test-get "
4118 cmdStr += setName + " " + values
4119 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004120 try:
Jon Halla495f562016-05-16 18:03:26 -07004121 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004122 # TODO: Maybe make this less hardcoded
4123 # ConsistentMap Exceptions
4124 assert "org.onosproject.store.service" not in output
4125 # Node not leader
4126 assert "java.lang.IllegalStateException" not in output
4127 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004128 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004129 "command: " + str( output ) )
4130 retryTime = 30 # Conservative time, given by Madan
4131 main.log.info( "Waiting " + str( retryTime ) +
4132 "seconds before retrying." )
4133 time.sleep( retryTime ) # Due to change in mastership
4134 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004135 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004136 assert "Command not found:" not in output, output
4137 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004138 main.log.info( self.name + ": " + output )
4139
4140 if length == 0:
4141 match = re.search( pattern, output )
4142 else: # if given values
4143 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004144 patternTrue = pattern + "\r\n" + containsTrue
4145 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004146 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004147 patternTrue = pattern + "\r\n" + containsAllTrue
4148 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004149 matchTrue = re.search( patternTrue, output )
4150 matchFalse = re.search( patternFalse, output )
4151 if matchTrue:
4152 containsCheck = main.TRUE
4153 match = matchTrue
4154 elif matchFalse:
4155 containsCheck = main.FALSE
4156 match = matchFalse
4157 else:
4158 main.log.error( self.name + " setTestGet did not match " +\
4159 "expected output" )
4160 main.log.debug( self.name + " expected: " + pattern )
4161 main.log.debug( self.name + " actual: " + repr( output ) )
4162 match = None
4163 if match:
4164 setMatch = match.group( 1 )
4165 if setMatch == '':
4166 setList = []
4167 else:
4168 setList = setMatch.split( ", " )
4169 if length > 0:
4170 return ( setList, containsCheck )
4171 else:
4172 return setList
4173 else: # no match
4174 main.log.error( self.name + ": setTestGet did not" +
4175 " match expected output" )
4176 main.log.debug( self.name + " expected: " + pattern )
4177 main.log.debug( self.name + " actual: " + repr( output ) )
4178 return main.ERROR
4179 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004180 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004181 return main.ERROR
4182 except TypeError:
4183 main.log.exception( self.name + ": Object not as expected" )
4184 return main.ERROR
4185 except pexpect.EOF:
4186 main.log.error( self.name + ": EOF exception found" )
4187 main.log.error( self.name + ": " + self.handle.before )
4188 main.cleanup()
4189 main.exit()
4190 except Exception:
4191 main.log.exception( self.name + ": Uncaught exception!" )
4192 main.cleanup()
4193 main.exit()
4194
4195 def setTestSize( self, setName ):
4196 """
4197 CLI command to get the elements in a distributed set.
4198 Required arguments:
4199 setName - The name of the set to remove from.
4200 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004201 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004202 None on error
4203 """
4204 try:
4205 # TODO: Should this check against the number of elements returned
4206 # and then return true/false based on that?
4207 setName = str( setName ).strip()
4208 # Patterns to match
4209 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004210 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004211 setPattern
4212 cmdStr = "set-test-get -s "
4213 cmdStr += setName
4214 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004215 try:
Jon Halla495f562016-05-16 18:03:26 -07004216 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004217 # TODO: Maybe make this less hardcoded
4218 # ConsistentMap Exceptions
4219 assert "org.onosproject.store.service" not in output
4220 # Node not leader
4221 assert "java.lang.IllegalStateException" not in output
4222 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004223 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004224 "command: " + str( output ) )
4225 retryTime = 30 # Conservative time, given by Madan
4226 main.log.info( "Waiting " + str( retryTime ) +
4227 "seconds before retrying." )
4228 time.sleep( retryTime ) # Due to change in mastership
4229 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004230 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004231 assert "Command not found:" not in output, output
4232 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004233 main.log.info( self.name + ": " + output )
4234 match = re.search( pattern, output )
4235 if match:
4236 setSize = int( match.group( 1 ) )
4237 setMatch = match.group( 2 )
4238 if len( setMatch.split() ) == setSize:
4239 main.log.info( "The size returned by " + self.name +
4240 " matches the number of elements in " +
4241 "the returned set" )
4242 else:
4243 main.log.error( "The size returned by " + self.name +
4244 " does not match the number of " +
4245 "elements in the returned set." )
4246 return setSize
4247 else: # no match
4248 main.log.error( self.name + ": setTestGet did not" +
4249 " match expected output" )
4250 main.log.debug( self.name + " expected: " + pattern )
4251 main.log.debug( self.name + " actual: " + repr( output ) )
4252 return None
4253 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004254 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004255 return None
Jon Hall390696c2015-05-05 17:13:41 -07004256 except TypeError:
4257 main.log.exception( self.name + ": Object not as expected" )
4258 return None
4259 except pexpect.EOF:
4260 main.log.error( self.name + ": EOF exception found" )
4261 main.log.error( self.name + ": " + self.handle.before )
4262 main.cleanup()
4263 main.exit()
4264 except Exception:
4265 main.log.exception( self.name + ": Uncaught exception!" )
4266 main.cleanup()
4267 main.exit()
4268
Jon Hall80daded2015-05-27 16:07:00 -07004269 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004270 """
4271 Command to list the various counters in the system.
4272 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004273 if jsonFormat, a string of the json object returned by the cli
4274 command
4275 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004276 None on error
4277 """
Jon Hall390696c2015-05-05 17:13:41 -07004278 try:
4279 counters = {}
4280 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004281 if jsonFormat:
4282 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004283 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004284 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004285 assert "Command not found:" not in output, output
4286 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004287 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004288 return output
Jon Hall390696c2015-05-05 17:13:41 -07004289 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004290 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004291 return None
Jon Hall390696c2015-05-05 17:13:41 -07004292 except TypeError:
4293 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004294 return None
Jon Hall390696c2015-05-05 17:13:41 -07004295 except pexpect.EOF:
4296 main.log.error( self.name + ": EOF exception found" )
4297 main.log.error( self.name + ": " + self.handle.before )
4298 main.cleanup()
4299 main.exit()
4300 except Exception:
4301 main.log.exception( self.name + ": Uncaught exception!" )
4302 main.cleanup()
4303 main.exit()
4304
Jon Hall935db192016-04-19 00:22:04 -07004305 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004306 """
Jon Halle1a3b752015-07-22 13:02:46 -07004307 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004308 Required arguments:
4309 counter - The name of the counter to increment.
4310 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004311 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004312 returns:
4313 integer value of the counter or
4314 None on Error
4315 """
4316 try:
4317 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004318 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004319 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004320 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004321 if delta != 1:
4322 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004323 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004324 try:
Jon Halla495f562016-05-16 18:03:26 -07004325 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004326 # TODO: Maybe make this less hardcoded
4327 # ConsistentMap Exceptions
4328 assert "org.onosproject.store.service" not in output
4329 # Node not leader
4330 assert "java.lang.IllegalStateException" not in output
4331 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004332 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004333 "command: " + str( output ) )
4334 retryTime = 30 # Conservative time, given by Madan
4335 main.log.info( "Waiting " + str( retryTime ) +
4336 "seconds before retrying." )
4337 time.sleep( retryTime ) # Due to change in mastership
4338 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004339 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004340 assert "Command not found:" not in output, output
4341 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004342 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004343 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004344 match = re.search( pattern, output )
4345 if match:
4346 return int( match.group( 1 ) )
4347 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004348 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004349 " match expected output." )
4350 main.log.debug( self.name + " expected: " + pattern )
4351 main.log.debug( self.name + " actual: " + repr( output ) )
4352 return None
4353 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004354 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004355 return None
4356 except TypeError:
4357 main.log.exception( self.name + ": Object not as expected" )
4358 return None
4359 except pexpect.EOF:
4360 main.log.error( self.name + ": EOF exception found" )
4361 main.log.error( self.name + ": " + self.handle.before )
4362 main.cleanup()
4363 main.exit()
4364 except Exception:
4365 main.log.exception( self.name + ": Uncaught exception!" )
4366 main.cleanup()
4367 main.exit()
4368
Jon Hall935db192016-04-19 00:22:04 -07004369 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004370 """
4371 CLI command to get a distributed counter then add a delta to it.
4372 Required arguments:
4373 counter - The name of the counter to increment.
4374 Optional arguments:
4375 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004376 returns:
4377 integer value of the counter or
4378 None on Error
4379 """
4380 try:
4381 counter = str( counter )
4382 delta = int( delta )
4383 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004384 cmdStr += counter
4385 if delta != 1:
4386 cmdStr += " " + str( delta )
4387 output = self.sendline( cmdStr )
4388 try:
Jon Halla495f562016-05-16 18:03:26 -07004389 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004390 # TODO: Maybe make this less hardcoded
4391 # ConsistentMap Exceptions
4392 assert "org.onosproject.store.service" not in output
4393 # Node not leader
4394 assert "java.lang.IllegalStateException" not in output
4395 except AssertionError:
4396 main.log.error( "Error in processing '" + cmdStr + "' " +
4397 "command: " + str( output ) )
4398 retryTime = 30 # Conservative time, given by Madan
4399 main.log.info( "Waiting " + str( retryTime ) +
4400 "seconds before retrying." )
4401 time.sleep( retryTime ) # Due to change in mastership
4402 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004403 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004404 assert "Command not found:" not in output, output
4405 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004406 main.log.info( self.name + ": " + output )
4407 pattern = counter + " was updated to (-?\d+)"
4408 match = re.search( pattern, output )
4409 if match:
4410 return int( match.group( 1 ) )
4411 else:
4412 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4413 " match expected output." )
4414 main.log.debug( self.name + " expected: " + pattern )
4415 main.log.debug( self.name + " actual: " + repr( output ) )
4416 return None
4417 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004418 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004419 return None
4420 except TypeError:
4421 main.log.exception( self.name + ": Object not as expected" )
4422 return None
4423 except pexpect.EOF:
4424 main.log.error( self.name + ": EOF exception found" )
4425 main.log.error( self.name + ": " + self.handle.before )
4426 main.cleanup()
4427 main.exit()
4428 except Exception:
4429 main.log.exception( self.name + ": Uncaught exception!" )
4430 main.cleanup()
4431 main.exit()
4432
YPZhangfebf7302016-05-24 16:45:56 -07004433 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004434 """
4435 Description: Execute summary command in onos
4436 Returns: json object ( summary -j ), returns main.FALSE if there is
4437 no output
4438
4439 """
4440 try:
4441 cmdStr = "summary"
4442 if jsonFormat:
4443 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004444 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004445 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004446 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004447 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004448 if not handle:
4449 main.log.error( self.name + ": There is no output in " +
4450 "summary command" )
4451 return main.FALSE
4452 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004453 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004454 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004455 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004456 except TypeError:
4457 main.log.exception( self.name + ": Object not as expected" )
4458 return None
4459 except pexpect.EOF:
4460 main.log.error( self.name + ": EOF exception found" )
4461 main.log.error( self.name + ": " + self.handle.before )
4462 main.cleanup()
4463 main.exit()
4464 except Exception:
4465 main.log.exception( self.name + ": Uncaught exception!" )
4466 main.cleanup()
4467 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004468
Jon Hall935db192016-04-19 00:22:04 -07004469 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004470 """
4471 CLI command to get the value of a key in a consistent map using
4472 transactions. This a test function and can only get keys from the
4473 test map hard coded into the cli command
4474 Required arguments:
4475 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004476 returns:
4477 The string value of the key or
4478 None on Error
4479 """
4480 try:
4481 keyName = str( keyName )
4482 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004483 cmdStr += keyName
4484 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004485 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004486 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004487 try:
4488 # TODO: Maybe make this less hardcoded
4489 # ConsistentMap Exceptions
4490 assert "org.onosproject.store.service" not in output
4491 # Node not leader
4492 assert "java.lang.IllegalStateException" not in output
4493 except AssertionError:
4494 main.log.error( "Error in processing '" + cmdStr + "' " +
4495 "command: " + str( output ) )
4496 return None
4497 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4498 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004499 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004500 return None
4501 else:
4502 match = re.search( pattern, output )
4503 if match:
4504 return match.groupdict()[ 'value' ]
4505 else:
4506 main.log.error( self.name + ": transactionlMapGet did not" +
4507 " match expected output." )
4508 main.log.debug( self.name + " expected: " + pattern )
4509 main.log.debug( self.name + " actual: " + repr( output ) )
4510 return None
Jon Hallc6793552016-01-19 14:18:37 -08004511 except AssertionError:
4512 main.log.exception( "" )
4513 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004514 except TypeError:
4515 main.log.exception( self.name + ": Object not as expected" )
4516 return None
4517 except pexpect.EOF:
4518 main.log.error( self.name + ": EOF exception found" )
4519 main.log.error( self.name + ": " + self.handle.before )
4520 main.cleanup()
4521 main.exit()
4522 except Exception:
4523 main.log.exception( self.name + ": Uncaught exception!" )
4524 main.cleanup()
4525 main.exit()
4526
Jon Hall935db192016-04-19 00:22:04 -07004527 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004528 """
4529 CLI command to put a value into 'numKeys' number of keys in a
4530 consistent map using transactions. This a test function and can only
4531 put into keys named 'Key#' of the test map hard coded into the cli command
4532 Required arguments:
4533 numKeys - Number of keys to add the value to
4534 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004535 returns:
4536 A dictionary whose keys are the name of the keys put into the map
4537 and the values of the keys are dictionaries whose key-values are
4538 'value': value put into map and optionaly
4539 'oldValue': Previous value in the key or
4540 None on Error
4541
4542 Example output
4543 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4544 'Key2': {'value': 'Testing'} }
4545 """
4546 try:
4547 numKeys = str( numKeys )
4548 value = str( value )
4549 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004550 cmdStr += numKeys + " " + value
4551 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004552 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004553 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004554 try:
4555 # TODO: Maybe make this less hardcoded
4556 # ConsistentMap Exceptions
4557 assert "org.onosproject.store.service" not in output
4558 # Node not leader
4559 assert "java.lang.IllegalStateException" not in output
4560 except AssertionError:
4561 main.log.error( "Error in processing '" + cmdStr + "' " +
4562 "command: " + str( output ) )
4563 return None
4564 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4565 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4566 results = {}
4567 for line in output.splitlines():
4568 new = re.search( newPattern, line )
4569 updated = re.search( updatedPattern, line )
4570 if new:
4571 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4572 elif updated:
4573 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004574 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004575 else:
4576 main.log.error( self.name + ": transactionlMapGet did not" +
4577 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004578 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4579 newPattern,
4580 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004581 main.log.debug( self.name + " actual: " + repr( output ) )
4582 return results
Jon Hallc6793552016-01-19 14:18:37 -08004583 except AssertionError:
4584 main.log.exception( "" )
4585 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004586 except TypeError:
4587 main.log.exception( self.name + ": Object not as expected" )
4588 return None
4589 except pexpect.EOF:
4590 main.log.error( self.name + ": EOF exception found" )
4591 main.log.error( self.name + ": " + self.handle.before )
4592 main.cleanup()
4593 main.exit()
4594 except Exception:
4595 main.log.exception( self.name + ": Uncaught exception!" )
4596 main.cleanup()
4597 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004598
acsmarsdaea66c2015-09-03 11:44:06 -07004599 def maps( self, jsonFormat=True ):
4600 """
4601 Description: Returns result of onos:maps
4602 Optional:
4603 * jsonFormat: enable json formatting of output
4604 """
4605 try:
4606 cmdStr = "maps"
4607 if jsonFormat:
4608 cmdStr += " -j"
4609 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004610 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004611 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004612 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004613 except AssertionError:
4614 main.log.exception( "" )
4615 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004616 except TypeError:
4617 main.log.exception( self.name + ": Object not as expected" )
4618 return None
4619 except pexpect.EOF:
4620 main.log.error( self.name + ": EOF exception found" )
4621 main.log.error( self.name + ": " + self.handle.before )
4622 main.cleanup()
4623 main.exit()
4624 except Exception:
4625 main.log.exception( self.name + ": Uncaught exception!" )
4626 main.cleanup()
4627 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004628
4629 def getSwController( self, uri, jsonFormat=True ):
4630 """
4631 Descrition: Gets the controller information from the device
4632 """
4633 try:
4634 cmd = "device-controllers "
4635 if jsonFormat:
4636 cmd += "-j "
4637 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004638 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004639 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004640 return response
Jon Hallc6793552016-01-19 14:18:37 -08004641 except AssertionError:
4642 main.log.exception( "" )
4643 return None
GlennRC050596c2015-11-18 17:06:41 -08004644 except TypeError:
4645 main.log.exception( self.name + ": Object not as expected" )
4646 return None
4647 except pexpect.EOF:
4648 main.log.error( self.name + ": EOF exception found" )
4649 main.log.error( self.name + ": " + self.handle.before )
4650 main.cleanup()
4651 main.exit()
4652 except Exception:
4653 main.log.exception( self.name + ": Uncaught exception!" )
4654 main.cleanup()
4655 main.exit()
4656
4657 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4658 """
4659 Descrition: sets the controller(s) for the specified device
4660
4661 Parameters:
4662 Required: uri - String: The uri of the device(switch).
4663 ip - String or List: The ip address of the controller.
4664 This parameter can be formed in a couple of different ways.
4665 VALID:
4666 10.0.0.1 - just the ip address
4667 tcp:10.0.0.1 - the protocol and the ip address
4668 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4669 so that you can add controllers with different
4670 protocols and ports
4671 INVALID:
4672 10.0.0.1:6653 - this is not supported by ONOS
4673
4674 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4675 port - The port number.
4676 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4677
4678 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4679 """
4680 try:
4681 cmd = "device-setcontrollers"
4682
4683 if jsonFormat:
4684 cmd += " -j"
4685 cmd += " " + uri
4686 if isinstance( ip, str ):
4687 ip = [ip]
4688 for item in ip:
4689 if ":" in item:
4690 sitem = item.split( ":" )
4691 if len(sitem) == 3:
4692 cmd += " " + item
4693 elif "." in sitem[1]:
4694 cmd += " {}:{}".format(item, port)
4695 else:
4696 main.log.error( "Malformed entry: " + item )
4697 raise TypeError
4698 else:
4699 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004700 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004701 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004702 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004703 if "Error" in response:
4704 main.log.error( response )
4705 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004706 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004707 except AssertionError:
4708 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004709 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004710 except TypeError:
4711 main.log.exception( self.name + ": Object not as expected" )
4712 return main.FALSE
4713 except pexpect.EOF:
4714 main.log.error( self.name + ": EOF exception found" )
4715 main.log.error( self.name + ": " + self.handle.before )
4716 main.cleanup()
4717 main.exit()
4718 except Exception:
4719 main.log.exception( self.name + ": Uncaught exception!" )
4720 main.cleanup()
4721 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004722
4723 def removeDevice( self, device ):
4724 '''
4725 Description:
4726 Remove a device from ONOS by passing the uri of the device(s).
4727 Parameters:
4728 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4729 Returns:
4730 Returns main.FALSE if an exception is thrown or an error is present
4731 in the response. Otherwise, returns main.TRUE.
4732 NOTE:
4733 If a host cannot be removed, then this function will return main.FALSE
4734 '''
4735 try:
4736 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004737 deviceStr = device
4738 device = []
4739 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004740
4741 for d in device:
4742 time.sleep( 1 )
4743 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004744 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004745 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004746 if "Error" in response:
4747 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4748 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004749 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004750 except AssertionError:
4751 main.log.exception( "" )
4752 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004753 except TypeError:
4754 main.log.exception( self.name + ": Object not as expected" )
4755 return main.FALSE
4756 except pexpect.EOF:
4757 main.log.error( self.name + ": EOF exception found" )
4758 main.log.error( self.name + ": " + self.handle.before )
4759 main.cleanup()
4760 main.exit()
4761 except Exception:
4762 main.log.exception( self.name + ": Uncaught exception!" )
4763 main.cleanup()
4764 main.exit()
4765
4766 def removeHost( self, host ):
4767 '''
4768 Description:
4769 Remove a host from ONOS by passing the id of the host(s)
4770 Parameters:
4771 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4772 Returns:
4773 Returns main.FALSE if an exception is thrown or an error is present
4774 in the response. Otherwise, returns main.TRUE.
4775 NOTE:
4776 If a host cannot be removed, then this function will return main.FALSE
4777 '''
4778 try:
4779 if type( host ) is str:
4780 host = list( host )
4781
4782 for h in host:
4783 time.sleep( 1 )
4784 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004785 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004786 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004787 if "Error" in response:
4788 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4789 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004790 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004791 except AssertionError:
4792 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004793 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004794 except TypeError:
4795 main.log.exception( self.name + ": Object not as expected" )
4796 return main.FALSE
4797 except pexpect.EOF:
4798 main.log.error( self.name + ": EOF exception found" )
4799 main.log.error( self.name + ": " + self.handle.before )
4800 main.cleanup()
4801 main.exit()
4802 except Exception:
4803 main.log.exception( self.name + ": Uncaught exception!" )
4804 main.cleanup()
4805 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004806
YPZhangfebf7302016-05-24 16:45:56 -07004807 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004808 '''
4809 Description:
4810 Bring link down or up in the null-provider.
4811 params:
4812 begin - (string) One end of a device or switch.
4813 end - (string) the other end of the device or switch
4814 returns:
4815 main.TRUE if no exceptions were thrown and no Errors are
4816 present in the resoponse. Otherwise, returns main.FALSE
4817 '''
4818 try:
Jon Hallc6793552016-01-19 14:18:37 -08004819 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004820 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004821 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004822 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004823 if "Error" in response or "Failure" in response:
4824 main.log.error( response )
4825 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004826 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004827 except AssertionError:
4828 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004829 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004830 except TypeError:
4831 main.log.exception( self.name + ": Object not as expected" )
4832 return main.FALSE
4833 except pexpect.EOF:
4834 main.log.error( self.name + ": EOF exception found" )
4835 main.log.error( self.name + ": " + self.handle.before )
4836 main.cleanup()
4837 main.exit()
4838 except Exception:
4839 main.log.exception( self.name + ": Uncaught exception!" )
4840 main.cleanup()
4841 main.exit()
4842
Jon Hall2c8959e2016-12-16 12:17:34 -08004843 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004844 '''
4845 Description:
4846 Changes the state of port in an OF switch by means of the
4847 PORTSTATUS OF messages.
4848 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004849 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4850 port - (string) target port in the device. Ex: '2'
4851 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004852 returns:
4853 main.TRUE if no exceptions were thrown and no Errors are
4854 present in the resoponse. Otherwise, returns main.FALSE
4855 '''
4856 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004857 state = state.lower()
4858 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004859 cmd = "portstate {} {} {}".format( dpid, port, state )
4860 response = self.sendline( cmd, showResponse=True )
4861 assert response is not None, "Error in sendline"
4862 assert "Command not found:" not in response, response
4863 if "Error" in response or "Failure" in response:
4864 main.log.error( response )
4865 return main.FALSE
4866 return main.TRUE
4867 except AssertionError:
4868 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004869 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004870 except TypeError:
4871 main.log.exception( self.name + ": Object not as expected" )
4872 return main.FALSE
4873 except pexpect.EOF:
4874 main.log.error( self.name + ": EOF exception found" )
4875 main.log.error( self.name + ": " + self.handle.before )
4876 main.cleanup()
4877 main.exit()
4878 except Exception:
4879 main.log.exception( self.name + ": Uncaught exception!" )
4880 main.cleanup()
4881 main.exit()
4882
4883 def logSet( self, level="INFO", app="org.onosproject" ):
4884 """
4885 Set the logging level to lvl for a specific app
4886 returns main.TRUE on success
4887 returns main.FALSE if Error occurred
4888 if noExit is True, TestON will not exit, but clean up
4889 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4890 Level defaults to INFO
4891 """
4892 try:
4893 self.handle.sendline( "log:set %s %s" %( level, app ) )
4894 self.handle.expect( "onos>" )
4895
4896 response = self.handle.before
4897 if re.search( "Error", response ):
4898 return main.FALSE
4899 return main.TRUE
4900 except pexpect.TIMEOUT:
4901 main.log.exception( self.name + ": TIMEOUT exception found" )
4902 main.cleanup()
4903 main.exit()
4904 except pexpect.EOF:
4905 main.log.error( self.name + ": EOF exception found" )
4906 main.log.error( self.name + ": " + self.handle.before )
4907 main.cleanup()
4908 main.exit()
4909 except Exception:
4910 main.log.exception( self.name + ": Uncaught exception!" )
4911 main.cleanup()
4912 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004913
4914 def getGraphDict( self, timeout=60, includeHost=False ):
4915 """
4916 Return a dictionary which describes the latest network topology data as a
4917 graph.
4918 An example of the dictionary:
4919 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4920 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4921 Each vertex should at least have an 'edges' attribute which describes the
4922 adjacency information. The value of 'edges' attribute is also represented by
4923 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4924 list of attributes.
4925 An example of the edges dictionary:
4926 'edges': { vertex2: { 'port': ..., 'weight': ... },
4927 vertex3: { 'port': ..., 'weight': ... } }
4928 If includeHost == True, all hosts (and host-switch links) will be included
4929 in topology data.
4930 """
4931 graphDict = {}
4932 try:
4933 links = self.links()
4934 links = json.loads( links )
4935 devices = self.devices()
4936 devices = json.loads( devices )
4937 idToDevice = {}
4938 for device in devices:
4939 idToDevice[ device[ 'id' ] ] = device
4940 if includeHost:
4941 hosts = self.hosts()
4942 # FIXME: support 'includeHost' argument
4943 for link in links:
4944 nodeA = link[ 'src' ][ 'device' ]
4945 nodeB = link[ 'dst' ][ 'device' ]
4946 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4947 if not nodeA in graphDict.keys():
4948 graphDict[ nodeA ] = { 'edges':{},
4949 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4950 'type':idToDevice[ nodeA ][ 'type' ],
4951 'available':idToDevice[ nodeA ][ 'available' ],
4952 'role':idToDevice[ nodeA ][ 'role' ],
4953 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4954 'hw':idToDevice[ nodeA ][ 'hw' ],
4955 'sw':idToDevice[ nodeA ][ 'sw' ],
4956 'serial':idToDevice[ nodeA ][ 'serial' ],
4957 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4958 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4959 else:
4960 # Assert nodeB is not connected to any current links of nodeA
4961 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4962 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4963 'type':link[ 'type' ],
4964 'state':link[ 'state' ] }
4965 return graphDict
4966 except ( TypeError, ValueError ):
4967 main.log.exception( self.name + ": Object not as expected" )
4968 return None
4969 except KeyError:
4970 main.log.exception( self.name + ": KeyError exception found" )
4971 return None
4972 except AssertionError:
4973 main.log.exception( self.name + ": AssertionError exception found" )
4974 return None
4975 except pexpect.EOF:
4976 main.log.error( self.name + ": EOF exception found" )
4977 main.log.error( self.name + ": " + self.handle.before )
4978 return None
4979 except Exception:
4980 main.log.exception( self.name + ": Uncaught exception!" )
4981 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004982
4983 def getIntentPerfSummary( self ):
4984 '''
4985 Send command to check intent-perf summary
4986 Returns: dictionary for intent-perf summary
4987 if something wrong, function will return None
4988 '''
4989 cmd = "intent-perf -s"
4990 respDic = {}
4991 resp = self.sendline( cmd )
4992 try:
4993 # Generate the dictionary to return
4994 for l in resp.split( "\n" ):
4995 # Delete any white space in line
4996 temp = re.sub( r'\s+', '', l )
4997 temp = temp.split( ":" )
4998 respDic[ temp[0] ] = temp[ 1 ]
4999
5000 except (TypeError, ValueError):
5001 main.log.exception( self.name + ": Object not as expected" )
5002 return None
5003 except KeyError:
5004 main.log.exception( self.name + ": KeyError exception found" )
5005 return None
5006 except AssertionError:
5007 main.log.exception( self.name + ": AssertionError exception found" )
5008 return None
5009 except pexpect.EOF:
5010 main.log.error( self.name + ": EOF exception found" )
5011 main.log.error( self.name + ": " + self.handle.before )
5012 return None
5013 except Exception:
5014 main.log.exception( self.name + ": Uncaught exception!" )
5015 return None
5016 return respDic
5017
Chiyu Chengec63bde2016-11-17 18:11:36 -08005018 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005019 """
5020 Searches the latest ONOS log file for the given search term and
5021 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005022
chengchiyu08303a02016-09-08 17:40:26 -07005023 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005024 searchTerm:
5025 The string to grep from the ONOS log.
5026 startLine:
5027 The term that decides which line is the start to search the searchTerm in
5028 the karaf log. For now, startTerm only works in 'first' mode.
5029 logNum:
5030 In some extreme cases, one karaf log is not big enough to contain all the
5031 information.Because of this, search mutiply logs is necessary to capture
5032 the right result. logNum is the number of karaf logs that we need to search
5033 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005034 mode:
5035 all: return all the strings that contain the search term
5036 last: return the last string that contains the search term
5037 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005038 num: return the number of times that the searchTerm appears in the log
5039 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005040 """
5041 try:
5042 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005043 #Build the log paths string
5044 logPath = '/opt/onos/log/karaf.log.'
5045 logPaths = '/opt/onos/log/karaf.log'
5046 for i in range( 1, logNum ):
5047 logPaths = logPath + str( i ) + " " + logPaths
5048 cmd = "cat " + logPaths
5049 if mode == 'all':
5050 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005051 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005052 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005053 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005054 if startLine != '':
5055 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5056 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5057 else:
5058 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005059 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005060 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
5061 num = self.sendstartTerm=startTerm1, line( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005062 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005063 if mode == 'total':
5064 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5065 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005066 before = self.sendline( cmd )
5067 before = before.splitlines()
5068 # make sure the returned list only contains the search term
5069 returnLines = [line for line in before if searchTerm in line]
5070 return returnLines
5071 except AssertionError:
5072 main.log.error( self.name + " searchTerm is not string type" )
5073 return None
5074 except pexpect.EOF:
5075 main.log.error( self.name + ": EOF exception found" )
5076 main.log.error( self.name + ": " + self.handle.before )
5077 main.cleanup()
5078 main.exit()
5079 except pexpect.TIMEOUT:
5080 main.log.error( self.name + ": TIMEOUT exception found" )
5081 main.log.error( self.name + ": " + self.handle.before )
5082 main.cleanup()
5083 main.exit()
5084 except Exception:
5085 main.log.exception( self.name + ": Uncaught exception!" )
5086 main.cleanup()
5087 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005088
5089 def vplsShow( self, jsonFormat=True ):
5090 """
5091 Description: Returns result of onos:vpls show, which should list the
5092 configured VPLS networks and the assigned interfaces.
5093 Optional:
5094 * jsonFormat: enable json formatting of output
5095 Returns:
5096 The output of the command or None on error.
5097 """
5098 try:
5099 cmdStr = "vpls show"
5100 if jsonFormat:
5101 raise NotImplementedError
5102 cmdStr += " -j"
5103 handle = self.sendline( cmdStr )
5104 assert handle is not None, "Error in sendline"
5105 assert "Command not found:" not in handle, handle
5106 return handle
5107 except AssertionError:
5108 main.log.exception( "" )
5109 return None
5110 except TypeError:
5111 main.log.exception( self.name + ": Object not as expected" )
5112 return None
5113 except pexpect.EOF:
5114 main.log.error( self.name + ": EOF exception found" )
5115 main.log.error( self.name + ": " + self.handle.before )
5116 main.cleanup()
5117 main.exit()
5118 except NotImplementedError:
5119 main.log.exception( self.name + ": Json output not supported")
5120 return None
5121 except Exception:
5122 main.log.exception( self.name + ": Uncaught exception!" )
5123 main.cleanup()
5124 main.exit()
5125
5126 def parseVplsShow( self ):
5127 """
5128 Parse the cli output of 'vpls show' into json output. This is required
5129 as there is currently no json output available.
5130 """
5131 try:
5132 output = []
5133 raw = self.vplsShow( jsonFormat=False )
5134 namePat = "VPLS name: (?P<name>\w+)"
5135 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5136 encapPat = "Encapsulation: (?P<encap>\w+)"
5137 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5138 mIter = re.finditer( pattern, raw )
5139 for match in mIter:
5140 item = {}
5141 item[ 'name' ] = match.group( 'name' )
5142 ifaces = match.group( 'interfaces' ).split( ', ')
5143 if ifaces == [ "" ]:
5144 ifaces = []
5145 item[ 'interfaces' ] = ifaces
5146 encap = match.group( 'encap' )
5147 if encap != 'NONE':
5148 item[ 'encapsulation' ] = encap.lower()
5149 output.append( item )
5150 return output
5151 except Exception:
5152 main.log.exception( self.name + ": Uncaught exception!" )
5153 main.cleanup()
5154 main.exit()
5155
5156 def vplsList( self, jsonFormat=True ):
5157 """
5158 Description: Returns result of onos:vpls list, which should list the
5159 configured VPLS networks.
5160 Optional:
5161 * jsonFormat: enable json formatting of output
5162 """
5163 try:
5164 cmdStr = "vpls list"
5165 if jsonFormat:
5166 raise NotImplementedError
5167 cmdStr += " -j"
5168 handle = self.sendline( cmdStr )
5169 assert handle is not None, "Error in sendline"
5170 assert "Command not found:" not in handle, handle
5171 return handle
5172 except AssertionError:
5173 main.log.exception( "" )
5174 return None
5175 except TypeError:
5176 main.log.exception( self.name + ": Object not as expected" )
5177 return None
5178 except pexpect.EOF:
5179 main.log.error( self.name + ": EOF exception found" )
5180 main.log.error( self.name + ": " + self.handle.before )
5181 main.cleanup()
5182 main.exit()
5183 except NotImplementedError:
5184 main.log.exception( self.name + ": Json output not supported")
5185 return None
5186 except Exception:
5187 main.log.exception( self.name + ": Uncaught exception!" )
5188 main.cleanup()
5189 main.exit()
5190
5191 def vplsCreate( self, network ):
5192 """
5193 CLI command to create a new VPLS network.
5194 Required arguments:
5195 network - String name of the network to create.
5196 returns:
5197 main.TRUE on success and main.FALSE on failure
5198 """
5199 try:
5200 network = str( network )
5201 cmdStr = "vpls create "
5202 cmdStr += network
5203 output = self.sendline( cmdStr )
5204 assert output is not None, "Error in sendline"
5205 assert "Command not found:" not in output, output
5206 assert "Error executing command" not in output, output
5207 assert "VPLS already exists:" not in output, output
5208 return main.TRUE
5209 except AssertionError:
5210 main.log.exception( "" )
5211 return main.FALSE
5212 except TypeError:
5213 main.log.exception( self.name + ": Object not as expected" )
5214 return main.FALSE
5215 except pexpect.EOF:
5216 main.log.error( self.name + ": EOF exception found" )
5217 main.log.error( self.name + ": " + self.handle.before )
5218 main.cleanup()
5219 main.exit()
5220 except Exception:
5221 main.log.exception( self.name + ": Uncaught exception!" )
5222 main.cleanup()
5223 main.exit()
5224
5225 def vplsDelete( self, network ):
5226 """
5227 CLI command to delete a VPLS network.
5228 Required arguments:
5229 network - Name of the network to delete.
5230 returns:
5231 main.TRUE on success and main.FALSE on failure
5232 """
5233 try:
5234 network = str( network )
5235 cmdStr = "vpls delete "
5236 cmdStr += network
5237 output = self.sendline( cmdStr )
5238 assert output is not None, "Error in sendline"
5239 assert "Command not found:" not in output, output
5240 assert "Error executing command" not in output, output
5241 assert " not found" not in output, output
5242 return main.TRUE
5243 except AssertionError:
5244 main.log.exception( "" )
5245 return main.FALSE
5246 except TypeError:
5247 main.log.exception( self.name + ": Object not as expected" )
5248 return main.FALSE
5249 except pexpect.EOF:
5250 main.log.error( self.name + ": EOF exception found" )
5251 main.log.error( self.name + ": " + self.handle.before )
5252 main.cleanup()
5253 main.exit()
5254 except Exception:
5255 main.log.exception( self.name + ": Uncaught exception!" )
5256 main.cleanup()
5257 main.exit()
5258
5259 def vplsAddIface( self, network, iface ):
5260 """
5261 CLI command to add an interface to a VPLS network.
5262 Required arguments:
5263 network - Name of the network to add the interface to.
5264 iface - The ONOS name for an interface.
5265 returns:
5266 main.TRUE on success and main.FALSE on failure
5267 """
5268 try:
5269 network = str( network )
5270 iface = str( iface )
5271 cmdStr = "vpls add-if "
5272 cmdStr += network + " " + iface
5273 output = self.sendline( cmdStr )
5274 assert output is not None, "Error in sendline"
5275 assert "Command not found:" not in output, output
5276 assert "Error executing command" not in output, output
5277 assert "already associated to network" not in output, output
5278 assert "Interface cannot be added." not in output, output
5279 return main.TRUE
5280 except AssertionError:
5281 main.log.exception( "" )
5282 return main.FALSE
5283 except TypeError:
5284 main.log.exception( self.name + ": Object not as expected" )
5285 return main.FALSE
5286 except pexpect.EOF:
5287 main.log.error( self.name + ": EOF exception found" )
5288 main.log.error( self.name + ": " + self.handle.before )
5289 main.cleanup()
5290 main.exit()
5291 except Exception:
5292 main.log.exception( self.name + ": Uncaught exception!" )
5293 main.cleanup()
5294 main.exit()
5295
5296 def vplsRemIface( self, network, iface ):
5297 """
5298 CLI command to remove an interface from a VPLS network.
5299 Required arguments:
5300 network - Name of the network to remove the interface from.
5301 iface - Name of the interface to remove.
5302 returns:
5303 main.TRUE on success and main.FALSE on failure
5304 """
5305 try:
5306 iface = str( iface )
5307 cmdStr = "vpls rem-if "
5308 cmdStr += network + " " + iface
5309 output = self.sendline( cmdStr )
5310 assert output is not None, "Error in sendline"
5311 assert "Command not found:" not in output, output
5312 assert "Error executing command" not in output, output
5313 assert "is not configured" not in output, output
5314 return main.TRUE
5315 except AssertionError:
5316 main.log.exception( "" )
5317 return main.FALSE
5318 except TypeError:
5319 main.log.exception( self.name + ": Object not as expected" )
5320 return main.FALSE
5321 except pexpect.EOF:
5322 main.log.error( self.name + ": EOF exception found" )
5323 main.log.error( self.name + ": " + self.handle.before )
5324 main.cleanup()
5325 main.exit()
5326 except Exception:
5327 main.log.exception( self.name + ": Uncaught exception!" )
5328 main.cleanup()
5329 main.exit()
5330
5331 def vplsClean( self ):
5332 """
5333 Description: Clears the VPLS app configuration.
5334 Returns: main.TRUE on success and main.FALSE on failure
5335 """
5336 try:
5337 cmdStr = "vpls clean"
5338 handle = self.sendline( cmdStr )
5339 assert handle is not None, "Error in sendline"
5340 assert "Command not found:" not in handle, handle
5341 return handle
5342 except AssertionError:
5343 main.log.exception( "" )
5344 return main.FALSE
5345 except TypeError:
5346 main.log.exception( self.name + ": Object not as expected" )
5347 return main.FALSE
5348 except pexpect.EOF:
5349 main.log.error( self.name + ": EOF exception found" )
5350 main.log.error( self.name + ": " + self.handle.before )
5351 main.cleanup()
5352 main.exit()
5353 except Exception:
5354 main.log.exception( self.name + ": Uncaught exception!" )
5355 main.cleanup()
5356 main.exit()
5357
5358 def vplsSetEncap( self, network, encapType ):
5359 """
5360 CLI command to add an interface to a VPLS network.
5361 Required arguments:
5362 network - Name of the network to create.
5363 encapType - Type of encapsulation.
5364 returns:
5365 main.TRUE on success and main.FALSE on failure
5366 """
5367 try:
5368 network = str( network )
5369 encapType = str( encapType ).upper()
5370 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5371 cmdStr = "vpls set-encap "
5372 cmdStr += network + " " + encapType
5373 output = self.sendline( cmdStr )
5374 assert output is not None, "Error in sendline"
5375 assert "Command not found:" not in output, output
5376 assert "Error executing command" not in output, output
5377 assert "already associated to network" not in output, output
5378 assert "Encapsulation type " not in output, output
5379 return main.TRUE
5380 except AssertionError:
5381 main.log.exception( "" )
5382 return main.FALSE
5383 except TypeError:
5384 main.log.exception( self.name + ": Object not as expected" )
5385 return main.FALSE
5386 except pexpect.EOF:
5387 main.log.error( self.name + ": EOF exception found" )
5388 main.log.error( self.name + ": " + self.handle.before )
5389 main.cleanup()
5390 main.exit()
5391 except Exception:
5392 main.log.exception( self.name + ": Uncaught exception!" )
5393 main.cleanup()
5394 main.exit()
5395
5396 def interfaces( self, jsonFormat=True ):
5397 """
5398 Description: Returns result of interfaces command.
5399 Optional:
5400 * jsonFormat: enable json formatting of output
5401 Returns:
5402 The output of the command or None on error.
5403 """
5404 try:
5405 cmdStr = "interfaces"
5406 if jsonFormat:
5407 #raise NotImplementedError
5408 cmdStr += " -j"
5409 handle = self.sendline( cmdStr )
5410 assert handle is not None, "Error in sendline"
5411 assert "Command not found:" not in handle, handle
5412 return handle
5413 except AssertionError:
5414 main.log.exception( "" )
5415 return None
5416 except TypeError:
5417 main.log.exception( self.name + ": Object not as expected" )
5418 return None
5419 except pexpect.EOF:
5420 main.log.error( self.name + ": EOF exception found" )
5421 main.log.error( self.name + ": " + self.handle.before )
5422 main.cleanup()
5423 main.exit()
5424 except NotImplementedError:
5425 main.log.exception( self.name + ": Json output not supported")
5426 return None
5427 except Exception:
5428 main.log.exception( self.name + ": Uncaught exception!" )
5429 main.cleanup()
5430 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005431
5432 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5433 '''
5434 Get the timestamp of searchTerm from karaf log.
5435
5436 Arguments:
5437 splitTerm_before and splitTerm_after:
5438
5439 The terms that split the string that contains the timeStamp of
5440 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5441 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5442 and the splitTerm_after is "x"
5443
5444 others:
5445
5446 plz look at the "logsearch" Function in onosclidriver.py
5447
5448
5449 '''
5450 if logNum < 0:
5451 main.log.error("Get wrong log number ")
5452 return main.ERROR
5453 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5454 if len(lines) == 0:
5455 main.log.warn( "Captured timestamp string is empty" )
5456 return main.ERROR
5457 lines = lines[ 0 ]
5458 try:
5459 assert type(lines) is str
5460 # get the target value
5461 line = lines.split( splitTerm_before )
5462 key = line[ 1 ].split( splitTerm_after )
5463 return int( key[ 0 ] )
5464 except IndexError:
5465 main.log.warn( "Index Error!" )
5466 return main.ERROR
5467 except AssertionError:
5468 main.log.warn( "Search Term Not Found " )
5469 return main.ERROR