blob: 301eb43a57159117b0d82f4a3393317dff6b028f [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="",
Jon Hallc6793552016-01-19 14:18:37 -0800235 commandlineTimeout=10, onosStartTimeout=60 ):
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:
kelvin8ec71442015-01-15 16:57:00 -0800252 self.handle.sendline( "" )
253 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500255
256 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
kelvin8ec71442015-01-15 16:57:00 -0800260 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800262 i = self.handle.expect( [
263 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700264 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400265
266 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800268 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800269 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800270 "config:property-set -p org.apache.karaf.shell\
271 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800272 karafTimeout )
273 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400276 return main.TRUE
277 else:
kelvin8ec71442015-01-15 16:57:00 -0800278 # If failed, send ctrl+c to process and try again
279 main.log.info( "Starting CLI failed. Retrying..." )
280 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800281 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800282 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
283 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400284 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800286 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800287 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800288 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 "config:property-set -p org.apache.karaf.shell\
290 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800291 karafTimeout )
292 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400295 return main.TRUE
296 else:
kelvin8ec71442015-01-15 16:57:00 -0800297 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400299 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400300
Jon Halld4d4b372015-01-28 16:02:41 -0800301 except TypeError:
302 main.log.exception( self.name + ": Object not as expected" )
303 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800305 main.log.error( self.name + ": EOF exception found" )
306 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400307 main.cleanup()
308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800310 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400311 main.cleanup()
312 main.exit()
313
suibin zhang116647a2016-05-06 16:30:09 -0700314 def startCellCli( self, karafTimeout="",
315 commandlineTimeout=10, onosStartTimeout=60 ):
316 """
317 Start CLI on onos ecll handle.
318
319 karafTimeout is an optional argument. karafTimeout value passed
320 by user would be used to set the current karaf shell idle timeout.
321 Note that when ever this property is modified the shell will exit and
322 the subsequent login would reflect new idle timeout.
323 Below is an example to start a session with 60 seconds idle timeout
324 ( input value is in milliseconds ):
325
326 tValue = "60000"
327
328 Note: karafTimeout is left as str so that this could be read
329 and passed to startOnosCli from PARAMS file as str.
330 """
331
332 try:
333 self.handle.sendline( "" )
334 x = self.handle.expect( [
335 "\$", "onos>" ], commandlineTimeout)
336
337 if x == 1:
338 main.log.info( "ONOS cli is already running" )
339 return main.TRUE
340
341 # Wait for onos start ( -w ) and enter onos cli
342 self.handle.sendline( "/opt/onos/bin/onos" )
343 i = self.handle.expect( [
344 "onos>",
345 pexpect.TIMEOUT ], onosStartTimeout )
346
347 if i == 0:
348 main.log.info( self.name + " CLI Started successfully" )
349 if karafTimeout:
350 self.handle.sendline(
351 "config:property-set -p org.apache.karaf.shell\
352 sshIdleTimeout " +
353 karafTimeout )
354 self.handle.expect( "\$" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 self.handle.expect( "onos>" )
357 return main.TRUE
358 else:
359 # If failed, send ctrl+c to process and try again
360 main.log.info( "Starting CLI failed. Retrying..." )
361 self.handle.send( "\x03" )
362 self.handle.sendline( "/opt/onos/bin/onos" )
363 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
364 timeout=30 )
365 if i == 0:
366 main.log.info( self.name + " CLI Started " +
367 "successfully after retry attempt" )
368 if karafTimeout:
369 self.handle.sendline(
370 "config:property-set -p org.apache.karaf.shell\
371 sshIdleTimeout " +
372 karafTimeout )
373 self.handle.expect( "\$" )
374 self.handle.sendline( "/opt/onos/bin/onos" )
375 self.handle.expect( "onos>" )
376 return main.TRUE
377 else:
378 main.log.error( "Connection to CLI " +
379 self.name + " timeout" )
380 return main.FALSE
381
382 except TypeError:
383 main.log.exception( self.name + ": Object not as expected" )
384 return None
385 except pexpect.EOF:
386 main.log.error( self.name + ": EOF exception found" )
387 main.log.error( self.name + ": " + self.handle.before )
388 main.cleanup()
389 main.exit()
390 except Exception:
391 main.log.exception( self.name + ": Uncaught exception!" )
392 main.cleanup()
393 main.exit()
394
YPZhangebf9eb52016-05-12 15:20:24 -0700395 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800399 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700400 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800401 Available level: DEBUG, TRACE, INFO, WARN, ERROR
402 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800403 """
404 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800405 lvlStr = ""
406 if level:
407 lvlStr = "--level=" + level
408
kelvin-onlab338f5512015-02-06 10:53:16 -0800409 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700410 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800411 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800412
kelvin-onlab9f541032015-02-04 16:19:53 -0800413 response = self.handle.before
414 if re.search( "Error", response ):
415 return main.FALSE
416 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700417 except pexpect.TIMEOUT:
418 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700419 if noExit:
420 main.cleanup()
421 return None
422 else:
423 main.cleanup()
424 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 except pexpect.EOF:
426 main.log.error( self.name + ": EOF exception found" )
427 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700428 if noExit:
429 main.cleanup()
430 return None
431 else:
432 main.cleanup()
433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800434 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800435 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700436 if noExit:
437 main.cleanup()
438 return None
439 else:
440 main.cleanup()
441 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400442
YPZhangebf9eb52016-05-12 15:20:24 -0700443 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800444 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800445 Send a completely user specified string to
446 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400447 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800448
YPZhang14a4aa92016-07-15 13:37:15 -0700449 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700450
andrewonlaba18f6bf2014-10-13 19:31:54 -0400451 Warning: There are no sanity checking to commands
452 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800453
kelvin8ec71442015-01-15 16:57:00 -0800454 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400455 try:
Jon Halla495f562016-05-16 18:03:26 -0700456 # Try to reconnect if disconnected from cli
457 self.handle.sendline( "" )
458 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
459 if i == 1:
460 main.log.error( self.name + ": onos cli session closed. ")
461 if self.onosIp:
462 main.log.warn( "Trying to reconnect " + self.onosIp )
463 reconnectResult = self.startOnosCli( self.onosIp )
464 if reconnectResult:
465 main.log.info( self.name + ": onos cli session reconnected." )
466 else:
467 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700468 if noExit:
469 return None
470 else:
471 main.cleanup()
472 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700473 else:
474 main.cleanup()
475 main.exit()
476 if i == 2:
477 self.handle.sendline( "" )
478 self.handle.expect( "onos>" )
479
Jon Hall14a03b52016-05-11 12:07:30 -0700480 if debug:
481 # NOTE: This adds and average of .4 seconds per call
482 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700483 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800484 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800485 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800486 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800487 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800488 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
489 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700491 main.log.debug( self.name + ": Raw output" )
492 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700493
494 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800495 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800496 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700498 main.log.debug( self.name + ": ansiEscape output" )
499 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700500
kelvin-onlabfb521662015-02-27 09:52:40 -0800501 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800502 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700504 main.log.debug( self.name + ": Removed extra returns " +
505 "from output" )
506 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700507
508 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800509 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700510 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700511 main.log.debug( self.name + ": parsed and stripped output" )
512 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700513
Jon Hall63604932015-02-26 17:09:50 -0800514 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 output = response.split( cmdStr.strip(), 1 )
516 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700517 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700519 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800520 output = output[1].strip()
521 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800522 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800523 return output
GlennRCed771242016-01-13 17:02:47 -0800524 except pexpect.TIMEOUT:
525 main.log.error( self.name + ":ONOS timeout" )
526 if debug:
527 main.log.debug( self.handle.before )
528 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700529 except IndexError:
530 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700531 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800533 except TypeError:
534 main.log.exception( self.name + ": Object not as expected" )
535 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400536 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800537 main.log.error( self.name + ": EOF exception found" )
538 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700539 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700540 return None
541 else:
542 main.cleanup()
543 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800544 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800545 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700546 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700547 return None
548 else:
549 main.cleanup()
550 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400551
kelvin8ec71442015-01-15 16:57:00 -0800552 # IMPORTANT NOTE:
553 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 # the cli command changing 'a:b' with 'aB'.
555 # Ex ) onos:topology > onosTopology
556 # onos:links > onosLinks
557 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800558
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400561 Adds a new cluster node by ID and address information.
562 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 * nodeId
564 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800566 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800567 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400568 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 cmdStr = "add-node " + str( nodeId ) + " " +\
570 str( ONOSIp ) + " " + str( tcpPort )
571 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700572 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800573 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800574 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800575 main.log.error( "Error in adding node" )
576 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800577 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400578 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400580 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800581 except AssertionError:
582 main.log.exception( "" )
583 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800584 except TypeError:
585 main.log.exception( self.name + ": Object not as expected" )
586 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800588 main.log.error( self.name + ": EOF exception found" )
589 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590 main.cleanup()
591 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800592 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800593 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400594 main.cleanup()
595 main.exit()
596
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800598 """
andrewonlab86dc3082014-10-13 18:18:38 -0400599 Removes a cluster by ID
600 Issues command: 'remove-node [<node-id>]'
601 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800603 """
andrewonlab86dc3082014-10-13 18:18:38 -0400604 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400605
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700607 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700608 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800609 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700610 if re.search( "Error", handle ):
611 main.log.error( "Error in removing node" )
612 main.log.error( handle )
613 return main.FALSE
614 else:
615 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800616 except AssertionError:
617 main.log.exception( "" )
618 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800619 except TypeError:
620 main.log.exception( self.name + ": Object not as expected" )
621 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800623 main.log.error( self.name + ": EOF exception found" )
624 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400625 main.cleanup()
626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800627 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800628 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400629 main.cleanup()
630 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400631
Jon Hall61282e32015-03-19 11:34:11 -0700632 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800633 """
andrewonlab7c211572014-10-15 16:45:20 -0400634 List the nodes currently visible
635 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700636 Optional argument:
637 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800638 """
andrewonlab7c211572014-10-15 16:45:20 -0400639 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700640 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700641 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700642 cmdStr += " -j"
643 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700644 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800645 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700646 return output
Jon Hallc6793552016-01-19 14:18:37 -0800647 except AssertionError:
648 main.log.exception( "" )
649 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800650 except TypeError:
651 main.log.exception( self.name + ": Object not as expected" )
652 return None
andrewonlab7c211572014-10-15 16:45:20 -0400653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800654 main.log.error( self.name + ": EOF exception found" )
655 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400656 main.cleanup()
657 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800658 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800659 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400660 main.cleanup()
661 main.exit()
662
kelvin8ec71442015-01-15 16:57:00 -0800663 def topology( self ):
664 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700665 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700666 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700667 Return:
668 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800669 """
andrewonlab95ce8322014-10-13 14:12:04 -0400670 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700671 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800672 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800673 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700674 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400675 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800676 except AssertionError:
677 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800678 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800679 except TypeError:
680 main.log.exception( self.name + ": Object not as expected" )
681 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800683 main.log.error( self.name + ": EOF exception found" )
684 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400685 main.cleanup()
686 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800687 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800688 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400689 main.cleanup()
690 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800691
jenkins7ead5a82015-03-13 10:28:21 -0700692 def deviceRemove( self, deviceId ):
693 """
694 Removes particular device from storage
695
696 TODO: refactor this function
697 """
698 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700699 cmdStr = "device-remove " + str( deviceId )
700 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800701 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700702 if re.search( "Error", handle ):
703 main.log.error( "Error in removing device" )
704 main.log.error( handle )
705 return main.FALSE
706 else:
707 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800708 except AssertionError:
709 main.log.exception( "" )
710 return None
jenkins7ead5a82015-03-13 10:28:21 -0700711 except TypeError:
712 main.log.exception( self.name + ": Object not as expected" )
713 return None
714 except pexpect.EOF:
715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
717 main.cleanup()
718 main.exit()
719 except Exception:
720 main.log.exception( self.name + ": Uncaught exception!" )
721 main.cleanup()
722 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700723
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800725 """
Jon Hall7b02d952014-10-17 20:14:54 -0400726 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400727 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800729 """
andrewonlab86dc3082014-10-13 18:18:38 -0400730 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700731 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700733 cmdStr += " -j"
734 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800735 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700736 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800737 except AssertionError:
738 main.log.exception( "" )
739 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800740 except TypeError:
741 main.log.exception( self.name + ": Object not as expected" )
742 return None
andrewonlab7c211572014-10-15 16:45:20 -0400743 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800744 main.log.error( self.name + ": EOF exception found" )
745 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400746 main.cleanup()
747 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800748 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800749 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400750 main.cleanup()
751 main.exit()
752
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800754 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800755 This balances the devices across all controllers
756 by issuing command: 'onos> onos:balance-masters'
757 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800758 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800759 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700761 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800762 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700763 if re.search( "Error", handle ):
764 main.log.error( "Error in balancing masters" )
765 main.log.error( handle )
766 return main.FALSE
767 else:
768 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800769 except AssertionError:
770 main.log.exception( "" )
771 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800772 except TypeError:
773 main.log.exception( self.name + ": Object not as expected" )
774 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800775 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800776 main.log.error( self.name + ": EOF exception found" )
777 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800778 main.cleanup()
779 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800780 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800781 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800782 main.cleanup()
783 main.exit()
784
Jon Hallc6793552016-01-19 14:18:37 -0800785 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700786 """
787 Returns the output of the masters command.
788 Optional argument:
789 * jsonFormat - boolean indicating if you want output in json
790 """
791 try:
792 cmdStr = "onos:masters"
793 if jsonFormat:
794 cmdStr += " -j"
795 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700796 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800797 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700798 return output
Jon Hallc6793552016-01-19 14:18:37 -0800799 except AssertionError:
800 main.log.exception( "" )
801 return None
acsmars24950022015-07-30 18:00:43 -0700802 except TypeError:
803 main.log.exception( self.name + ": Object not as expected" )
804 return None
805 except pexpect.EOF:
806 main.log.error( self.name + ": EOF exception found" )
807 main.log.error( self.name + ": " + self.handle.before )
808 main.cleanup()
809 main.exit()
810 except Exception:
811 main.log.exception( self.name + ": Uncaught exception!" )
812 main.cleanup()
813 main.exit()
814
Jon Hallc6793552016-01-19 14:18:37 -0800815 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700816 """
817 Uses the master command to check that the devices' leadership
818 is evenly divided
819
820 Dependencies: checkMasters() and summary()
821
Jon Hall6509dbf2016-06-21 17:01:17 -0700822 Returns main.TRUE if the devices are balanced
823 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700824 Exits on Exception
825 Returns None on TypeError
826 """
827 try:
Jon Hallc6793552016-01-19 14:18:37 -0800828 summaryOutput = self.summary()
829 totalDevices = json.loads( summaryOutput )[ "devices" ]
830 except ( TypeError, ValueError ):
831 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
832 return None
833 try:
acsmars24950022015-07-30 18:00:43 -0700834 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800835 mastersOutput = self.checkMasters()
836 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700837 first = masters[ 0 ][ "size" ]
838 for master in masters:
839 totalOwnedDevices += master[ "size" ]
840 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
841 main.log.error( "Mastership not balanced" )
842 main.log.info( "\n" + self.checkMasters( False ) )
843 return main.FALSE
844 main.log.info( "Mastership balanced between " \
845 + str( len(masters) ) + " masters" )
846 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800847 except ( TypeError, ValueError ):
848 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700849 return None
850 except pexpect.EOF:
851 main.log.error( self.name + ": EOF exception found" )
852 main.log.error( self.name + ": " + self.handle.before )
853 main.cleanup()
854 main.exit()
855 except Exception:
856 main.log.exception( self.name + ": Uncaught exception!" )
857 main.cleanup()
858 main.exit()
859
YPZhangfebf7302016-05-24 16:45:56 -0700860 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800861 """
Jon Halle8217482014-10-17 13:49:14 -0400862 Lists all core links
863 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800865 """
Jon Halle8217482014-10-17 13:49:14 -0400866 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700867 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700869 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700870 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800871 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700872 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800873 except AssertionError:
874 main.log.exception( "" )
875 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800876 except TypeError:
877 main.log.exception( self.name + ": Object not as expected" )
878 return None
Jon Halle8217482014-10-17 13:49:14 -0400879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800880 main.log.error( self.name + ": EOF exception found" )
881 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400882 main.cleanup()
883 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800884 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800885 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400886 main.cleanup()
887 main.exit()
888
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800890 """
Jon Halle8217482014-10-17 13:49:14 -0400891 Lists all ports
892 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800894 """
Jon Halle8217482014-10-17 13:49:14 -0400895 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700896 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700898 cmdStr += " -j"
899 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800900 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700901 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800902 except AssertionError:
903 main.log.exception( "" )
904 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800905 except TypeError:
906 main.log.exception( self.name + ": Object not as expected" )
907 return None
Jon Halle8217482014-10-17 13:49:14 -0400908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800909 main.log.error( self.name + ": EOF exception found" )
910 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400911 main.cleanup()
912 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800913 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800914 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400915 main.cleanup()
916 main.exit()
917
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800919 """
Jon Hall983a1702014-10-28 18:44:22 -0400920 Lists all devices and the controllers with roles assigned to them
921 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800923 """
andrewonlab7c211572014-10-15 16:45:20 -0400924 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700925 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700927 cmdStr += " -j"
928 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800929 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700930 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800931 except AssertionError:
932 main.log.exception( "" )
933 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800934 except TypeError:
935 main.log.exception( self.name + ": Object not as expected" )
936 return None
Jon Hall983a1702014-10-28 18:44:22 -0400937 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800938 main.log.error( self.name + ": EOF exception found" )
939 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400940 main.cleanup()
941 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800942 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800943 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400944 main.cleanup()
945 main.exit()
946
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800948 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800949 Given the a string containing the json representation of the "roles"
950 cli command and a partial or whole device id, returns a json object
951 containing the roles output for the first device whose id contains
952 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400953
954 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 A dict of the role assignments for the given device or
956 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800957 """
Jon Hall983a1702014-10-28 18:44:22 -0400958 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400960 return None
961 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 rawRoles = self.roles()
963 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800964 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800966 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400968 return device
969 return None
Jon Hallc6793552016-01-19 14:18:37 -0800970 except ( TypeError, ValueError ):
971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800972 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400973 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400976 main.cleanup()
977 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800979 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400980 main.cleanup()
981 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800984 """
Jon Hall94fd0472014-12-08 11:52:42 -0800985 Iterates through each device and checks if there is a master assigned
986 Returns: main.TRUE if each device has a master
987 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800990 rawRoles = self.roles()
991 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800992 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800994 # print device
995 if device[ 'master' ] == "none":
996 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800997 return main.FALSE
998 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800999 except ( TypeError, ValueError ):
1000 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001001 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001002 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001003 main.log.error( self.name + ": EOF exception found" )
1004 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001005 main.cleanup()
1006 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001007 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001008 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001009 main.cleanup()
1010 main.exit()
1011
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001013 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001014 Returns string of paths, and the cost.
1015 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001016 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001017 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001018 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1019 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001020 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001021 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001022 main.log.error( "Error in getting paths" )
1023 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001024 else:
kelvin8ec71442015-01-15 16:57:00 -08001025 path = handle.split( ";" )[ 0 ]
1026 cost = handle.split( ";" )[ 1 ]
1027 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001028 except AssertionError:
1029 main.log.exception( "" )
1030 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001031 except TypeError:
1032 main.log.exception( self.name + ": Object not as expected" )
1033 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001034 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001035 main.log.error( self.name + ": EOF exception found" )
1036 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 main.cleanup()
1038 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001039 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001040 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001041 main.cleanup()
1042 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Hallffb386d2014-11-21 13:43:38 -08001046 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001047 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001049 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001051 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr += " -j"
1054 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001055 if handle:
1056 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001057 # TODO: Maybe make this less hardcoded
1058 # ConsistentMap Exceptions
1059 assert "org.onosproject.store.service" not in handle
1060 # Node not leader
1061 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001062 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001063 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001064 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001065 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001066 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001067 except TypeError:
1068 main.log.exception( self.name + ": Object not as expected" )
1069 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001073 main.cleanup()
1074 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001077 main.cleanup()
1078 main.exit()
1079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001081 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001082 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001083
Jon Hallefbd9792015-03-05 16:11:36 -08001084 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001085 partial mac address
1086
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001088 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 try:
kelvin8ec71442015-01-15 16:57:00 -08001090 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001091 return None
1092 else:
1093 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 rawHosts = self.hosts()
1095 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001096 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001097 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001098 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001099 if not host:
1100 pass
1101 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001102 return host
1103 return None
Jon Hallc6793552016-01-19 14:18:37 -08001104 except ( TypeError, ValueError ):
1105 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001106 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001107 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001108 main.log.error( self.name + ": EOF exception found" )
1109 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001110 main.cleanup()
1111 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001112 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001113 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001114 main.cleanup()
1115 main.exit()
1116
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001118 """
1119 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001120 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001121
andrewonlab3f0a4af2014-10-17 12:25:14 -04001122 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 IMPORTANT:
1125 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001126 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127 Furthermore, it assumes that value of VLAN is '-1'
1128 Description:
kelvin8ec71442015-01-15 16:57:00 -08001129 Converts mininet hosts ( h1, h2, h3... ) into
1130 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1131 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001132 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001136 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 hostHex = hex( int( host ) ).zfill( 12 )
1138 hostHex = str( hostHex ).replace( 'x', '0' )
1139 i = iter( str( hostHex ) )
1140 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1141 hostHex = hostHex + "/-1"
1142 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001143
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001145
Jon Halld4d4b372015-01-28 16:02:41 -08001146 except TypeError:
1147 main.log.exception( self.name + ": Object not as expected" )
1148 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001150 main.log.error( self.name + ": EOF exception found" )
1151 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001152 main.cleanup()
1153 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001154 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001155 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001156 main.cleanup()
1157 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001158
Jeremy Songsterff553672016-05-12 17:06:23 -07001159 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlabe6745342014-10-17 14:29:13 -04001161 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 * hostIdOne: ONOS host id for host1
1163 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001164 Optional:
1165 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001166 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001167 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001168 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001169 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 Returns:
1171 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001172 """
andrewonlabe6745342014-10-17 14:29:13 -04001173 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001174 cmdStr = "add-host-intent "
1175 if vlanId:
1176 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001177 if setVlan:
1178 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001179 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001181 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001182 if re.search( "Error", handle ):
1183 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001184 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001186 else:
1187 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1189 match = re.search('id=0x([\da-f]+),', handle)
1190 if match:
1191 return match.group()[3:-1]
1192 else:
1193 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001194 main.log.debug( "Response from ONOS was: " +
1195 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 return None
Jon Hallc6793552016-01-19 14:18:37 -08001197 except AssertionError:
1198 main.log.exception( "" )
1199 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001200 except TypeError:
1201 main.log.exception( self.name + ": Object not as expected" )
1202 return None
andrewonlabe6745342014-10-17 14:29:13 -04001203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( self.name + ": EOF exception found" )
1205 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001206 main.cleanup()
1207 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001208 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001209 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001210 main.cleanup()
1211 main.exit()
1212
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001214 """
andrewonlab7b31d232014-10-24 13:31:47 -04001215 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 * ingressDevice: device id of ingress device
1217 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001218 Optional:
1219 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001220 Description:
1221 Adds an optical intent by specifying an ingress and egress device
1222 Returns:
1223 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001224 """
andrewonlab7b31d232014-10-24 13:31:47 -04001225 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1227 " " + str( egressDevice )
1228 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001229 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001230 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001231 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 main.log.error( "Error in adding Optical intent" )
1233 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001234 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 main.log.info( "Optical intent installed between " +
1236 str( ingressDevice ) + " and " +
1237 str( egressDevice ) )
1238 match = re.search('id=0x([\da-f]+),', handle)
1239 if match:
1240 return match.group()[3:-1]
1241 else:
1242 main.log.error( "Error, intent ID not found" )
1243 return None
Jon Hallc6793552016-01-19 14:18:37 -08001244 except AssertionError:
1245 main.log.exception( "" )
1246 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001247 except TypeError:
1248 main.log.exception( self.name + ": Object not as expected" )
1249 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001253 main.cleanup()
1254 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001255 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001256 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001257 main.cleanup()
1258 main.exit()
1259
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001261 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 ingressDevice,
1263 egressDevice,
1264 portIngress="",
1265 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001266 ethType="",
1267 ethSrc="",
1268 ethDst="",
1269 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001271 ipProto="",
1272 ipSrc="",
1273 ipDst="",
1274 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001275 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001276 vlanId="",
1277 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001278 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001279 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * ingressDevice: device id of ingress device
1281 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001282 Optional:
1283 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001284 * ethSrc: specify ethSrc ( i.e. src mac addr )
1285 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001286 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001288 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001289 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001290 * ipSrc: specify ip source address
1291 * ipDst: specify ip destination address
1292 * tcpSrc: specify tcp source port
1293 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001294 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001295 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001296 Description:
kelvin8ec71442015-01-15 16:57:00 -08001297 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001298 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 Returns:
1300 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001301
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001303 options developers provide for point-to-point
1304 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001305 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001306 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001307 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001308
Jeremy Songsterff553672016-05-12 17:06:23 -07001309 if ethType:
1310 cmd += " --ethType " + str( ethType )
1311 if ethSrc:
1312 cmd += " --ethSrc " + str( ethSrc )
1313 if ethDst:
1314 cmd += " --ethDst " + str( ethDst )
1315 if bandwidth:
1316 cmd += " --bandwidth " + str( bandwidth )
1317 if lambdaAlloc:
1318 cmd += " --lambda "
1319 if ipProto:
1320 cmd += " --ipProto " + str( ipProto )
1321 if ipSrc:
1322 cmd += " --ipSrc " + str( ipSrc )
1323 if ipDst:
1324 cmd += " --ipDst " + str( ipDst )
1325 if tcpSrc:
1326 cmd += " --tcpSrc " + str( tcpSrc )
1327 if tcpDst:
1328 cmd += " --tcpDst " + str( tcpDst )
1329 if vlanId:
1330 cmd += " -v " + str( vlanId )
1331 if setVlan:
1332 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001333
kelvin8ec71442015-01-15 16:57:00 -08001334 # Check whether the user appended the port
1335 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 if "/" in ingressDevice:
1337 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001338 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001341 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001342 # Would it make sense to throw an exception and exit
1343 # the test?
1344 return None
andrewonlab36af3822014-11-18 17:48:18 -05001345
kelvin8ec71442015-01-15 16:57:00 -08001346 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 str( ingressDevice ) + "/" +\
1348 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001349
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 if "/" in egressDevice:
1351 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001352 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001354 main.log.error( "You must specify the egress port" )
1355 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001356
kelvin8ec71442015-01-15 16:57:00 -08001357 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 str( egressDevice ) + "/" +\
1359 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001360
kelvin-onlab898a6c62015-01-16 14:13:53 -08001361 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001362 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001363 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001364 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001365 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001366 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001367 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 # TODO: print out all the options in this message?
1369 main.log.info( "Point-to-point intent installed between " +
1370 str( ingressDevice ) + " and " +
1371 str( egressDevice ) )
1372 match = re.search('id=0x([\da-f]+),', handle)
1373 if match:
1374 return match.group()[3:-1]
1375 else:
1376 main.log.error( "Error, intent ID not found" )
1377 return None
Jon Hallc6793552016-01-19 14:18:37 -08001378 except AssertionError:
1379 main.log.exception( "" )
1380 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001381 except TypeError:
1382 main.log.exception( self.name + ": Object not as expected" )
1383 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001384 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001385 main.log.error( self.name + ": EOF exception found" )
1386 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001387 main.cleanup()
1388 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001389 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001390 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001391 main.cleanup()
1392 main.exit()
1393
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001395 self,
shahshreyac2f97072015-03-19 17:04:29 -07001396 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001398 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001400 ethType="",
1401 ethSrc="",
1402 ethDst="",
1403 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001405 ipProto="",
1406 ipSrc="",
1407 ipDst="",
1408 tcpSrc="",
1409 tcpDst="",
1410 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001411 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001412 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001413 setVlan="",
1414 partial=False ):
kelvin8ec71442015-01-15 16:57:00 -08001415 """
shahshreyad0c80432014-12-04 16:56:05 -08001416 Note:
shahshreya70622b12015-03-19 17:19:00 -07001417 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001418 is same. That is, all ingress devices include port numbers
1419 with a "/" or all ingress devices could specify device
1420 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001421 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001422 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001423 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001425 Optional:
1426 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001427 * ethSrc: specify ethSrc ( i.e. src mac addr )
1428 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001429 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001431 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001432 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001433 * ipSrc: specify ip source address
1434 * ipDst: specify ip destination address
1435 * tcpSrc: specify tcp source port
1436 * tcpDst: specify tcp destination port
1437 * setEthSrc: action to Rewrite Source MAC Address
1438 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001439 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001440 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001441 Description:
kelvin8ec71442015-01-15 16:57:00 -08001442 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001443 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001444 Returns:
1445 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001446
Jon Halle3f39ff2015-01-13 11:50:53 -08001447 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001448 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001449 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001450 """
shahshreyad0c80432014-12-04 16:56:05 -08001451 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001452 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001453
Jeremy Songsterff553672016-05-12 17:06:23 -07001454 if ethType:
1455 cmd += " --ethType " + str( ethType )
1456 if ethSrc:
1457 cmd += " --ethSrc " + str( ethSrc )
1458 if ethDst:
1459 cmd += " --ethDst " + str( ethDst )
1460 if bandwidth:
1461 cmd += " --bandwidth " + str( bandwidth )
1462 if lambdaAlloc:
1463 cmd += " --lambda "
1464 if ipProto:
1465 cmd += " --ipProto " + str( ipProto )
1466 if ipSrc:
1467 cmd += " --ipSrc " + str( ipSrc )
1468 if ipDst:
1469 cmd += " --ipDst " + str( ipDst )
1470 if tcpSrc:
1471 cmd += " --tcpSrc " + str( tcpSrc )
1472 if tcpDst:
1473 cmd += " --tcpDst " + str( tcpDst )
1474 if setEthSrc:
1475 cmd += " --setEthSrc " + str( setEthSrc )
1476 if setEthDst:
1477 cmd += " --setEthDst " + str( setEthDst )
1478 if vlanId:
1479 cmd += " -v " + str( vlanId )
1480 if setVlan:
1481 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001482 if partial:
1483 cmd += " --partial"
shahshreyad0c80432014-12-04 16:56:05 -08001484
kelvin8ec71442015-01-15 16:57:00 -08001485 # Check whether the user appended the port
1486 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001487
1488 if portIngressList is None:
1489 for ingressDevice in ingressDeviceList:
1490 if "/" in ingressDevice:
1491 cmd += " " + str( ingressDevice )
1492 else:
1493 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001494 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001495 # TODO: perhaps more meaningful return
1496 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001497 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001498 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001499 for ingressDevice, portIngress in zip( ingressDeviceList,
1500 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001501 cmd += " " + \
1502 str( ingressDevice ) + "/" +\
1503 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001504 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001505 main.log.error( "Device list and port list does not " +
1506 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001507 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 if "/" in egressDevice:
1509 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001510 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001512 main.log.error( "You must specify " +
1513 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001514 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001515
kelvin8ec71442015-01-15 16:57:00 -08001516 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 str( egressDevice ) + "/" +\
1518 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001519 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001520 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001521 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001522 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001523 main.log.error( "Error in adding multipoint-to-singlepoint " +
1524 "intent" )
1525 return None
shahshreyad0c80432014-12-04 16:56:05 -08001526 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001527 match = re.search('id=0x([\da-f]+),', handle)
1528 if match:
1529 return match.group()[3:-1]
1530 else:
1531 main.log.error( "Error, intent ID not found" )
1532 return None
Jon Hallc6793552016-01-19 14:18:37 -08001533 except AssertionError:
1534 main.log.exception( "" )
1535 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001536 except TypeError:
1537 main.log.exception( self.name + ": Object not as expected" )
1538 return None
1539 except pexpect.EOF:
1540 main.log.error( self.name + ": EOF exception found" )
1541 main.log.error( self.name + ": " + self.handle.before )
1542 main.cleanup()
1543 main.exit()
1544 except Exception:
1545 main.log.exception( self.name + ": Uncaught exception!" )
1546 main.cleanup()
1547 main.exit()
1548
1549 def addSinglepointToMultipointIntent(
1550 self,
1551 ingressDevice,
1552 egressDeviceList,
1553 portIngress="",
1554 portEgressList=None,
1555 ethType="",
1556 ethSrc="",
1557 ethDst="",
1558 bandwidth="",
1559 lambdaAlloc=False,
1560 ipProto="",
1561 ipSrc="",
1562 ipDst="",
1563 tcpSrc="",
1564 tcpDst="",
1565 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001566 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001567 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001568 setVlan="",
1569 partial=False ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001570 """
1571 Note:
1572 This function assumes the format of all egress devices
1573 is same. That is, all egress devices include port numbers
1574 with a "/" or all egress devices could specify device
1575 ids and port numbers seperately.
1576 Required:
1577 * EgressDeviceList: List of device ids of egress device
1578 ( Atleast 2 eress devices required in the list )
1579 * ingressDevice: device id of ingress device
1580 Optional:
1581 * ethType: specify ethType
1582 * ethSrc: specify ethSrc ( i.e. src mac addr )
1583 * ethDst: specify ethDst ( i.e. dst mac addr )
1584 * bandwidth: specify bandwidth capacity of link
1585 * lambdaAlloc: if True, intent will allocate lambda
1586 for the specified intent
1587 * ipProto: specify ip protocol
1588 * ipSrc: specify ip source address
1589 * ipDst: specify ip destination address
1590 * tcpSrc: specify tcp source port
1591 * tcpDst: specify tcp destination port
1592 * setEthSrc: action to Rewrite Source MAC Address
1593 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001594 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001595 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001596 Description:
1597 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1598 specifying device id's and optional fields
1599 Returns:
1600 A string of the intent id or None on error
1601
1602 NOTE: This function may change depending on the
1603 options developers provide for singlepoint-to-multipoint
1604 intent via cli
1605 """
1606 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001607 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001608
Jeremy Songsterff553672016-05-12 17:06:23 -07001609 if ethType:
1610 cmd += " --ethType " + str( ethType )
1611 if ethSrc:
1612 cmd += " --ethSrc " + str( ethSrc )
1613 if ethDst:
1614 cmd += " --ethDst " + str( ethDst )
1615 if bandwidth:
1616 cmd += " --bandwidth " + str( bandwidth )
1617 if lambdaAlloc:
1618 cmd += " --lambda "
1619 if ipProto:
1620 cmd += " --ipProto " + str( ipProto )
1621 if ipSrc:
1622 cmd += " --ipSrc " + str( ipSrc )
1623 if ipDst:
1624 cmd += " --ipDst " + str( ipDst )
1625 if tcpSrc:
1626 cmd += " --tcpSrc " + str( tcpSrc )
1627 if tcpDst:
1628 cmd += " --tcpDst " + str( tcpDst )
1629 if setEthSrc:
1630 cmd += " --setEthSrc " + str( setEthSrc )
1631 if setEthDst:
1632 cmd += " --setEthDst " + str( setEthDst )
1633 if vlanId:
1634 cmd += " -v " + str( vlanId )
1635 if setVlan:
1636 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001637 if partial:
1638 cmd += " --partial"
kelvin-onlabb9408212015-04-01 13:34:04 -07001639
1640 # Check whether the user appended the port
1641 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001642
kelvin-onlabb9408212015-04-01 13:34:04 -07001643 if "/" in ingressDevice:
1644 cmd += " " + str( ingressDevice )
1645 else:
1646 if not portIngress:
1647 main.log.error( "You must specify " +
1648 "the Ingress port" )
1649 return main.FALSE
1650
1651 cmd += " " +\
1652 str( ingressDevice ) + "/" +\
1653 str( portIngress )
1654
1655 if portEgressList is None:
1656 for egressDevice in egressDeviceList:
1657 if "/" in egressDevice:
1658 cmd += " " + str( egressDevice )
1659 else:
1660 main.log.error( "You must specify " +
1661 "the egress port" )
1662 # TODO: perhaps more meaningful return
1663 return main.FALSE
1664 else:
1665 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001666 for egressDevice, portEgress in zip( egressDeviceList,
1667 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001668 cmd += " " + \
1669 str( egressDevice ) + "/" +\
1670 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001671 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001672 main.log.error( "Device list and port list does not " +
1673 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001674 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001675 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001676 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001677 # If error, return error message
1678 if re.search( "Error", handle ):
1679 main.log.error( "Error in adding singlepoint-to-multipoint " +
1680 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001681 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001682 else:
1683 match = re.search('id=0x([\da-f]+),', handle)
1684 if match:
1685 return match.group()[3:-1]
1686 else:
1687 main.log.error( "Error, intent ID not found" )
1688 return None
Jon Hallc6793552016-01-19 14:18:37 -08001689 except AssertionError:
1690 main.log.exception( "" )
1691 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001692 except TypeError:
1693 main.log.exception( self.name + ": Object not as expected" )
1694 return None
shahshreyad0c80432014-12-04 16:56:05 -08001695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001696 main.log.error( self.name + ": EOF exception found" )
1697 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001698 main.cleanup()
1699 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001700 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001701 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001702 main.cleanup()
1703 main.exit()
1704
Hari Krishna9e232602015-04-13 17:29:08 -07001705 def addMplsIntent(
1706 self,
1707 ingressDevice,
1708 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001709 ingressPort="",
1710 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001711 ethType="",
1712 ethSrc="",
1713 ethDst="",
1714 bandwidth="",
1715 lambdaAlloc=False,
1716 ipProto="",
1717 ipSrc="",
1718 ipDst="",
1719 tcpSrc="",
1720 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001721 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001722 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001723 priority=""):
1724 """
1725 Required:
1726 * ingressDevice: device id of ingress device
1727 * egressDevice: device id of egress device
1728 Optional:
1729 * ethType: specify ethType
1730 * ethSrc: specify ethSrc ( i.e. src mac addr )
1731 * ethDst: specify ethDst ( i.e. dst mac addr )
1732 * bandwidth: specify bandwidth capacity of link
1733 * lambdaAlloc: if True, intent will allocate lambda
1734 for the specified intent
1735 * ipProto: specify ip protocol
1736 * ipSrc: specify ip source address
1737 * ipDst: specify ip destination address
1738 * tcpSrc: specify tcp source port
1739 * tcpDst: specify tcp destination port
1740 * ingressLabel: Ingress MPLS label
1741 * egressLabel: Egress MPLS label
1742 Description:
1743 Adds MPLS intent by
1744 specifying device id's and optional fields
1745 Returns:
1746 A string of the intent id or None on error
1747
1748 NOTE: This function may change depending on the
1749 options developers provide for MPLS
1750 intent via cli
1751 """
1752 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001753 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001754
Jeremy Songsterff553672016-05-12 17:06:23 -07001755 if ethType:
1756 cmd += " --ethType " + str( ethType )
1757 if ethSrc:
1758 cmd += " --ethSrc " + str( ethSrc )
1759 if ethDst:
1760 cmd += " --ethDst " + str( ethDst )
1761 if bandwidth:
1762 cmd += " --bandwidth " + str( bandwidth )
1763 if lambdaAlloc:
1764 cmd += " --lambda "
1765 if ipProto:
1766 cmd += " --ipProto " + str( ipProto )
1767 if ipSrc:
1768 cmd += " --ipSrc " + str( ipSrc )
1769 if ipDst:
1770 cmd += " --ipDst " + str( ipDst )
1771 if tcpSrc:
1772 cmd += " --tcpSrc " + str( tcpSrc )
1773 if tcpDst:
1774 cmd += " --tcpDst " + str( tcpDst )
1775 if ingressLabel:
1776 cmd += " --ingressLabel " + str( ingressLabel )
1777 if egressLabel:
1778 cmd += " --egressLabel " + str( egressLabel )
1779 if priority:
1780 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001781
1782 # Check whether the user appended the port
1783 # or provided it as an input
1784 if "/" in ingressDevice:
1785 cmd += " " + str( ingressDevice )
1786 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001787 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001788 main.log.error( "You must specify the ingress port" )
1789 return None
1790
1791 cmd += " " + \
1792 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001793 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001794
1795 if "/" in egressDevice:
1796 cmd += " " + str( egressDevice )
1797 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001798 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001799 main.log.error( "You must specify the egress port" )
1800 return None
1801
1802 cmd += " " +\
1803 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001804 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001805
1806 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001807 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001808 # If error, return error message
1809 if re.search( "Error", handle ):
1810 main.log.error( "Error in adding mpls intent" )
1811 return None
1812 else:
1813 # TODO: print out all the options in this message?
1814 main.log.info( "MPLS intent installed between " +
1815 str( ingressDevice ) + " and " +
1816 str( egressDevice ) )
1817 match = re.search('id=0x([\da-f]+),', handle)
1818 if match:
1819 return match.group()[3:-1]
1820 else:
1821 main.log.error( "Error, intent ID not found" )
1822 return None
Jon Hallc6793552016-01-19 14:18:37 -08001823 except AssertionError:
1824 main.log.exception( "" )
1825 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001826 except TypeError:
1827 main.log.exception( self.name + ": Object not as expected" )
1828 return None
1829 except pexpect.EOF:
1830 main.log.error( self.name + ": EOF exception found" )
1831 main.log.error( self.name + ": " + self.handle.before )
1832 main.cleanup()
1833 main.exit()
1834 except Exception:
1835 main.log.exception( self.name + ": Uncaught exception!" )
1836 main.cleanup()
1837 main.exit()
1838
Jon Hallefbd9792015-03-05 16:11:36 -08001839 def removeIntent( self, intentId, app='org.onosproject.cli',
1840 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001841 """
shahshreya1c818fc2015-02-26 13:44:08 -08001842 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001843 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001844 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001845 -p or --purge: Purge the intent from the store after removal
1846
Jon Halle3f39ff2015-01-13 11:50:53 -08001847 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001848 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001849 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001850 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001851 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001852 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001853 if purge:
1854 cmdStr += " -p"
1855 if sync:
1856 cmdStr += " -s"
1857
1858 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001859 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001860 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001861 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001862 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001863 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001864 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001865 # TODO: Should this be main.TRUE
1866 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001867 except AssertionError:
1868 main.log.exception( "" )
1869 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001870 except TypeError:
1871 main.log.exception( self.name + ": Object not as expected" )
1872 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001874 main.log.error( self.name + ": EOF exception found" )
1875 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001876 main.cleanup()
1877 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001878 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001879 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001880 main.cleanup()
1881 main.exit()
1882
YPZhangfebf7302016-05-24 16:45:56 -07001883 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001884 """
1885 Description:
1886 Remove all the intents
1887 Optional args:-
1888 -s or --sync: Waits for the removal before returning
1889 -p or --purge: Purge the intent from the store after removal
1890 Returns:
1891 Returns main.TRUE if all intents are removed, otherwise returns
1892 main.FALSE; Returns None for exception
1893 """
1894 try:
1895 cmdStr = "remove-intent"
1896 if purge:
1897 cmdStr += " -p"
1898 if sync:
1899 cmdStr += " -s"
1900
1901 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001902 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001903 assert "Command not found:" not in handle, handle
1904 if re.search( "Error", handle ):
1905 main.log.error( "Error in removing intent" )
1906 return main.FALSE
1907 else:
1908 return main.TRUE
1909 except AssertionError:
1910 main.log.exception( "" )
1911 return None
1912 except TypeError:
1913 main.log.exception( self.name + ": Object not as expected" )
1914 return None
1915 except pexpect.EOF:
1916 main.log.error( self.name + ": EOF exception found" )
1917 main.log.error( self.name + ": " + self.handle.before )
1918 main.cleanup()
1919 main.exit()
1920 except Exception:
1921 main.log.exception( self.name + ": Uncaught exception!" )
1922 main.cleanup()
1923 main.exit()
1924
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001925 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001926 """
1927 Purges all WITHDRAWN Intents
1928 """
1929 try:
1930 cmdStr = "purge-intents"
1931 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001932 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001933 if re.search( "Error", handle ):
1934 main.log.error( "Error in purging intents" )
1935 return main.FALSE
1936 else:
1937 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001938 except AssertionError:
1939 main.log.exception( "" )
1940 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001941 except TypeError:
1942 main.log.exception( self.name + ": Object not as expected" )
1943 return None
1944 except pexpect.EOF:
1945 main.log.error( self.name + ": EOF exception found" )
1946 main.log.error( self.name + ": " + self.handle.before )
1947 main.cleanup()
1948 main.exit()
1949 except Exception:
1950 main.log.exception( self.name + ": Uncaught exception!" )
1951 main.cleanup()
1952 main.exit()
1953
kelvin-onlabd3b64892015-01-20 13:26:24 -08001954 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001955 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001956 NOTE: This method should be used after installing application:
1957 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001958 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001959 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001960 Description:
1961 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001962 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001963 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001964 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001965 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001966 cmdStr += " -j"
1967 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001968 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001969 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001970 except AssertionError:
1971 main.log.exception( "" )
1972 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001976 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001979 main.cleanup()
1980 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001981 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001982 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001983 main.cleanup()
1984 main.exit()
1985
pingping-lin54b03372015-08-13 14:43:10 -07001986 def ipv4RouteNumber( self ):
1987 """
1988 NOTE: This method should be used after installing application:
1989 onos-app-sdnip
1990 Description:
1991 Obtain the total IPv4 routes number in the system
1992 """
1993 try:
1994 cmdStr = "routes -s -j"
1995 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001996 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001997 jsonResult = json.loads( handle )
1998 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001999 except AssertionError:
2000 main.log.exception( "" )
2001 return None
2002 except ( TypeError, ValueError ):
2003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002004 return None
2005 except pexpect.EOF:
2006 main.log.error( self.name + ": EOF exception found" )
2007 main.log.error( self.name + ": " + self.handle.before )
2008 main.cleanup()
2009 main.exit()
2010 except Exception:
2011 main.log.exception( self.name + ": Uncaught exception!" )
2012 main.cleanup()
2013 main.exit()
2014
pingping-lin8244a3b2015-09-16 13:36:56 -07002015 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002016 """
andrewonlabe6745342014-10-17 14:29:13 -04002017 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002018 Obtain intents from the ONOS cli.
2019 Optional:
2020 * jsonFormat: Enable output formatting in json, default to True
2021 * summary: Whether only output the intent summary, defaults to False
2022 * type: Only output a certain type of intent. This options is valid
2023 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002024 """
andrewonlabe6745342014-10-17 14:29:13 -04002025 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002026 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002027 if summary:
2028 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002029 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002030 cmdStr += " -j"
2031 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002032 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002033 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002034 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002035 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002036 else:
Jon Hallff566d52016-01-15 14:45:36 -08002037 intentType = ""
2038 # IF we want the summary of a specific intent type
2039 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002040 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002041 if intentType in jsonResult.keys():
2042 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002043 else:
Jon Hallff566d52016-01-15 14:45:36 -08002044 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002045 return handle
2046 else:
2047 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002048 except AssertionError:
2049 main.log.exception( "" )
2050 return None
2051 except ( TypeError, ValueError ):
2052 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002053 return None
2054 except pexpect.EOF:
2055 main.log.error( self.name + ": EOF exception found" )
2056 main.log.error( self.name + ": " + self.handle.before )
2057 main.cleanup()
2058 main.exit()
2059 except Exception:
2060 main.log.exception( self.name + ": Uncaught exception!" )
2061 main.cleanup()
2062 main.exit()
2063
kelvin-onlab54400a92015-02-26 18:05:51 -08002064 def getIntentState(self, intentsId, intentsJson=None):
2065 """
You Wangfdcbfc42016-05-16 12:16:53 -07002066 Description:
2067 Gets intent state. Accepts a single intent ID (string type) or a
2068 list of intent IDs.
2069 Parameters:
2070 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002071 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002072 Returns:
2073 Returns the state (string type) of the ID if a single intent ID is
2074 accepted.
2075 Returns a list of dictionaries if a list of intent IDs is accepted,
2076 and each dictionary maps 'id' to the Intent ID and 'state' to
2077 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002078 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002079 try:
2080 state = "State is Undefined"
2081 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002082 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002083 else:
Jon Hallc6793552016-01-19 14:18:37 -08002084 rawJson = intentsJson
2085 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002086 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002087 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002088 if intentsId == intent[ 'id' ]:
2089 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002090 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002091 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2092 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002094 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002095 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002096 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002097 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002098 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002099 if intentsId[ i ] == intents[ 'id' ]:
2100 stateDict[ 'state' ] = intents[ 'state' ]
2101 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002102 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002103 break
Jon Hallefbd9792015-03-05 16:11:36 -08002104 if len( intentsId ) != len( dictList ):
2105 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002106 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002107 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002108 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 return None
Jon Hallc6793552016-01-19 14:18:37 -08002110 except ( TypeError, ValueError ):
2111 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002112 return None
2113 except pexpect.EOF:
2114 main.log.error( self.name + ": EOF exception found" )
2115 main.log.error( self.name + ": " + self.handle.before )
2116 main.cleanup()
2117 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002118 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002119 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002120 main.cleanup()
2121 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002122
kelvin-onlabf512e942015-06-08 19:42:59 -07002123 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002124 """
2125 Description:
2126 Check intents state
2127 Required:
2128 intentsId - List of intents ID to be checked
2129 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002130 expectedState - Check the expected state(s) of each intents
2131 state in the list.
2132 *NOTE: You can pass in a list of expected state,
2133 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002134 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002135 Returns main.TRUE only if all intent are the same as expected states
2136 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002137 """
2138 try:
2139 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002140 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002142 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002143 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002144 "getting intents state" )
2145 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002146
2147 if isinstance( expectedState, types.StringType ):
2148 for intents in intentsDict:
2149 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002150 main.log.debug( self.name + " : Intent ID - " +
2151 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002152 " actual state = " +
2153 intents.get( 'state' )
2154 + " does not equal expected state = "
2155 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002156 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002157
2158 elif isinstance( expectedState, types.ListType ):
2159 for intents in intentsDict:
2160 if not any( state == intents.get( 'state' ) for state in
2161 expectedState ):
2162 main.log.debug( self.name + " : Intent ID - " +
2163 intents.get( 'id' ) +
2164 " actual state = " +
2165 intents.get( 'state' ) +
2166 " does not equal expected states = "
2167 + str( expectedState ) )
2168 returnValue = main.FALSE
2169
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002170 if returnValue == main.TRUE:
2171 main.log.info( self.name + ": All " +
2172 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002173 " intents are in " + str( expectedState ) +
2174 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002175 return returnValue
2176 except TypeError:
2177 main.log.exception( self.name + ": Object not as expected" )
2178 return None
2179 except pexpect.EOF:
2180 main.log.error( self.name + ": EOF exception found" )
2181 main.log.error( self.name + ": " + self.handle.before )
2182 main.cleanup()
2183 main.exit()
2184 except Exception:
2185 main.log.exception( self.name + ": Uncaught exception!" )
2186 main.cleanup()
2187 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002188
You Wang66518af2016-05-16 15:32:59 -07002189 def compareIntent( self, intentDict ):
2190 """
2191 Description:
2192 Compare the intent ids and states provided in the argument with all intents in ONOS
2193 Return:
2194 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2195 Arguments:
2196 intentDict: a dictionary which maps intent ids to intent states
2197 """
2198 try:
2199 intentsRaw = self.intents()
2200 intentsJson = json.loads( intentsRaw )
2201 intentDictONOS = {}
2202 for intent in intentsJson:
2203 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2204 if len( intentDict ) != len( intentDictONOS ):
2205 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2206 str( len( intentDict ) ) + " expected and " +
2207 str( len( intentDictONOS ) ) + " actual" )
2208 return main.FALSE
2209 returnValue = main.TRUE
2210 for intentID in intentDict.keys():
2211 if not intentID in intentDictONOS.keys():
2212 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2213 returnValue = main.FALSE
2214 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2215 main.log.debug( self.name + ": intent ID - " + intentID +
2216 " expected state is " + intentDict[ intentID ] +
2217 " but actual state is " + intentDictONOS[ intentID ] )
2218 returnValue = main.FALSE
2219 if returnValue == main.TRUE:
2220 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2221 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002222 except KeyError:
2223 main.log.exception( self.name + ": KeyError exception found" )
2224 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002225 except ( TypeError, ValueError ):
2226 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002227 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002228 except pexpect.EOF:
2229 main.log.error( self.name + ": EOF exception found" )
2230 main.log.error( self.name + ": " + self.handle.before )
2231 main.cleanup()
2232 main.exit()
2233 except Exception:
2234 main.log.exception( self.name + ": Uncaught exception!" )
2235 main.cleanup()
2236 main.exit()
2237
YPZhang14a4aa92016-07-15 13:37:15 -07002238 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002239 """
2240 Description:
2241 Check the number of installed intents.
2242 Optional:
2243 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002244 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002245 Return:
2246 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2247 , otherwise, returns main.FALSE.
2248 """
2249
2250 try:
2251 cmd = "intents -s -j"
2252
2253 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002254 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002255 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002256 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002257 response = json.loads( response )
2258
2259 # get total and installed number, see if they are match
2260 allState = response.get( 'all' )
2261 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002262 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002263 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002264 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002265 return main.FALSE
2266
Jon Hallc6793552016-01-19 14:18:37 -08002267 except ( TypeError, ValueError ):
2268 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002269 return None
2270 except pexpect.EOF:
2271 main.log.error( self.name + ": EOF exception found" )
2272 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002273 if noExit:
2274 return main.FALSE
2275 else:
2276 main.cleanup()
2277 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002278 except Exception:
2279 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002280 if noExit:
2281 return main.FALSE
2282 else:
2283 main.cleanup()
2284 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002285 except pexpect.TIMEOUT:
2286 main.log.error( self.name + ": ONOS timeout" )
2287 return None
GlennRCed771242016-01-13 17:02:47 -08002288
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002289 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002290 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002291 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002293 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002294 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002295 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002296 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002297 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002298 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002299 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002300 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002301 if noCore:
2302 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002303 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002304 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002305 assert "Command not found:" not in handle, handle
2306 if re.search( "Error:", handle ):
2307 main.log.error( self.name + ": flows() response: " +
2308 str( handle ) )
2309 return handle
2310 except AssertionError:
2311 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002312 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002313 except TypeError:
2314 main.log.exception( self.name + ": Object not as expected" )
2315 return None
Jon Hallc6793552016-01-19 14:18:37 -08002316 except pexpect.TIMEOUT:
2317 main.log.error( self.name + ": ONOS timeout" )
2318 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002319 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002320 main.log.error( self.name + ": EOF exception found" )
2321 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002322 main.cleanup()
2323 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002324 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002325 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002326 main.cleanup()
2327 main.exit()
2328
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002329 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002330 count = self.getTotalFlowsNum( timeout=timeout )
2331 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002332 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002333
YPZhangebf9eb52016-05-12 15:20:24 -07002334 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002335 """
2336 Description:
GlennRCed771242016-01-13 17:02:47 -08002337 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002338 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2339 if the count of those states is 0, which means all current flows
2340 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002341 Optional:
GlennRCed771242016-01-13 17:02:47 -08002342 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002343 Return:
2344 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002345 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002346 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002347 """
2348 try:
GlennRCed771242016-01-13 17:02:47 -08002349 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2350 checkedStates = []
2351 statesCount = [0, 0, 0, 0]
2352 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002353 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002354 if rawFlows:
2355 # if we didn't get flows or flows function return None, we should return
2356 # main.Flase
2357 checkedStates.append( json.loads( rawFlows ) )
2358 else:
2359 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002360 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002361 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002362 try:
2363 statesCount[i] += int( c.get( "flowCount" ) )
2364 except TypeError:
2365 main.log.exception( "Json object not as expected" )
2366 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002367
GlennRCed771242016-01-13 17:02:47 -08002368 # We want to count PENDING_ADD if isPENDING is true
2369 if isPENDING:
2370 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2371 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002372 else:
GlennRCed771242016-01-13 17:02:47 -08002373 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2374 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002375 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002376 except ( TypeError, ValueError ):
2377 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002378 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002379
YPZhang240842b2016-05-17 12:00:50 -07002380 except AssertionError:
2381 main.log.exception( "" )
2382 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002383 except pexpect.EOF:
2384 main.log.error( self.name + ": EOF exception found" )
2385 main.log.error( self.name + ": " + self.handle.before )
2386 main.cleanup()
2387 main.exit()
2388 except Exception:
2389 main.log.exception( self.name + ": Uncaught exception!" )
2390 main.cleanup()
2391 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002392 except pexpect.TIMEOUT:
2393 main.log.error( self.name + ": ONOS timeout" )
2394 return None
2395
kelvin-onlab4df89f22015-04-13 18:10:23 -07002396
GlennRCed771242016-01-13 17:02:47 -08002397 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002398 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002399 """
andrewonlab87852b02014-11-19 18:44:19 -05002400 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002401 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002402 a specific point-to-point intent definition
2403 Required:
GlennRCed771242016-01-13 17:02:47 -08002404 * ingress: specify source dpid
2405 * egress: specify destination dpid
2406 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002407 Optional:
GlennRCed771242016-01-13 17:02:47 -08002408 * offset: the keyOffset is where the next batch of intents
2409 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002410 * noExit: If set to True, TestON will not exit if any error when issus command
2411 * getResponse: If set to True, function will return ONOS response.
2412
GlennRCed771242016-01-13 17:02:47 -08002413 Returns: If failed to push test intents, it will returen None,
2414 if successful, return true.
2415 Timeout expection will return None,
2416 TypeError will return false
2417 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002418 """
andrewonlab87852b02014-11-19 18:44:19 -05002419 try:
GlennRCed771242016-01-13 17:02:47 -08002420 if background:
2421 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002422 else:
GlennRCed771242016-01-13 17:02:47 -08002423 back = ""
2424 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002425 ingress,
2426 egress,
2427 batchSize,
2428 offset,
2429 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002430 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002431 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002432 main.log.info( response )
2433 if response == None:
2434 return None
2435
YPZhangb34b7e12016-06-14 14:28:19 -07002436 if getResponse:
2437 return response
2438
GlennRCed771242016-01-13 17:02:47 -08002439 # TODO: We should handle if there is failure in installation
2440 return main.TRUE
2441
Jon Hallc6793552016-01-19 14:18:37 -08002442 except AssertionError:
2443 main.log.exception( "" )
2444 return None
GlennRCed771242016-01-13 17:02:47 -08002445 except pexpect.TIMEOUT:
2446 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002447 return None
andrewonlab87852b02014-11-19 18:44:19 -05002448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002449 main.log.error( self.name + ": EOF exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002451 main.cleanup()
2452 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002453 except TypeError:
2454 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002455 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002456 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002457 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002458 main.cleanup()
2459 main.exit()
2460
YPZhangebf9eb52016-05-12 15:20:24 -07002461 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002462 """
2463 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002464 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002465 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002466 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002467 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002468 """
YPZhange3109a72016-02-02 11:25:37 -08002469
YPZhangb5d3f832016-01-23 22:54:26 -08002470 try:
YPZhange3109a72016-02-02 11:25:37 -08002471 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002472 cmd = "flows -c added"
2473 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2474 if rawFlows:
2475 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002476 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002477 for l in rawFlows:
2478 totalFlows += int(l.split("Count=")[1])
2479 else:
2480 main.log.error("Response not as expected!")
2481 return None
2482 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002483
You Wangd3cb2ce2016-05-16 14:01:24 -07002484 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002485 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002486 return None
2487 except pexpect.EOF:
2488 main.log.error( self.name + ": EOF exception found" )
2489 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002490 if not noExit:
2491 main.cleanup()
2492 main.exit()
2493 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002494 except Exception:
2495 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002496 if not noExit:
2497 main.cleanup()
2498 main.exit()
2499 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002500 except pexpect.TIMEOUT:
2501 main.log.error( self.name + ": ONOS timeout" )
2502 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002503
YPZhang14a4aa92016-07-15 13:37:15 -07002504 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002505 """
2506 Description:
2507 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002508 Optional:
2509 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002510 Return:
2511 The number of intents
2512 """
2513 try:
2514 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002515 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002516 if response == None:
2517 return -1
2518 response = json.loads( response )
2519 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002520 except ( TypeError, ValueError ):
2521 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002522 return None
2523 except pexpect.EOF:
2524 main.log.error( self.name + ": EOF exception found" )
2525 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002526 if noExit:
2527 return -1
2528 else:
2529 main.cleanup()
2530 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002531 except Exception:
2532 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002533 if noExit:
2534 return -1
2535 else:
2536 main.cleanup()
2537 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002538
kelvin-onlabd3b64892015-01-20 13:26:24 -08002539 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002540 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002541 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002542 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002543 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002544 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002545 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002546 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002547 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002548 cmdStr += " -j"
2549 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002550 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002551 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002552 except AssertionError:
2553 main.log.exception( "" )
2554 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002555 except TypeError:
2556 main.log.exception( self.name + ": Object not as expected" )
2557 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002558 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002559 main.log.error( self.name + ": EOF exception found" )
2560 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002561 main.cleanup()
2562 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002563 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002564 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002565 main.cleanup()
2566 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002567
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002569 """
2570 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002571 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002573 """
andrewonlab867212a2014-10-22 20:13:38 -04002574 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002575 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002576 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002577 cmdStr += " -j"
2578 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002579 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002580 if handle:
2581 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002582 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002583 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002584 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002585 else:
2586 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002587 except AssertionError:
2588 main.log.exception( "" )
2589 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002590 except TypeError:
2591 main.log.exception( self.name + ": Object not as expected" )
2592 return None
andrewonlab867212a2014-10-22 20:13:38 -04002593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002594 main.log.error( self.name + ": EOF exception found" )
2595 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002596 main.cleanup()
2597 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002598 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002599 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002600 main.cleanup()
2601 main.exit()
2602
kelvin8ec71442015-01-15 16:57:00 -08002603 # Wrapper functions ****************
2604 # Wrapper functions use existing driver
2605 # functions and extends their use case.
2606 # For example, we may use the output of
2607 # a normal driver function, and parse it
2608 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002609
kelvin-onlabd3b64892015-01-20 13:26:24 -08002610 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002611 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002612 Description:
2613 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002614 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002615 try:
kelvin8ec71442015-01-15 16:57:00 -08002616 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002617 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002619
kelvin8ec71442015-01-15 16:57:00 -08002620 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002621 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2622 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002623 match = re.search('id=0x([\da-f]+),', intents)
2624 if match:
2625 tmpId = match.group()[3:-1]
2626 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002628
Jon Halld4d4b372015-01-28 16:02:41 -08002629 except TypeError:
2630 main.log.exception( self.name + ": Object not as expected" )
2631 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002632 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002633 main.log.error( self.name + ": EOF exception found" )
2634 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002635 main.cleanup()
2636 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002637 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002638 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002639 main.cleanup()
2640 main.exit()
2641
Jon Hall30b82fa2015-03-04 17:15:43 -08002642 def FlowAddedCount( self, deviceId ):
2643 """
2644 Determine the number of flow rules for the given device id that are
2645 in the added state
2646 """
2647 try:
2648 cmdStr = "flows any " + str( deviceId ) + " | " +\
2649 "grep 'state=ADDED' | wc -l"
2650 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002651 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002652 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002653 except AssertionError:
2654 main.log.exception( "" )
2655 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002656 except pexpect.EOF:
2657 main.log.error( self.name + ": EOF exception found" )
2658 main.log.error( self.name + ": " + self.handle.before )
2659 main.cleanup()
2660 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002661 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002662 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002663 main.cleanup()
2664 main.exit()
2665
kelvin-onlabd3b64892015-01-20 13:26:24 -08002666 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002667 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002668 Use 'devices' function to obtain list of all devices
2669 and parse the result to obtain a list of all device
2670 id's. Returns this list. Returns empty list if no
2671 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002672 List is ordered sequentially
2673
andrewonlab3e15ead2014-10-15 14:21:34 -04002674 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002675 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002676 the ids. By obtaining the list of device ids on the fly,
2677 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002678 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002679 try:
kelvin8ec71442015-01-15 16:57:00 -08002680 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002681 devicesStr = self.devices( jsonFormat=False )
2682 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002683
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002685 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 return idList
kelvin8ec71442015-01-15 16:57:00 -08002687
2688 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002689 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002690 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002691 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002692 # Split list further into arguments before and after string
2693 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002694 # append to idList
2695 for arg in tempList:
2696 idList.append( arg.split( "id=" )[ 1 ] )
2697 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002698
Jon Halld4d4b372015-01-28 16:02:41 -08002699 except TypeError:
2700 main.log.exception( self.name + ": Object not as expected" )
2701 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002702 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002703 main.log.error( self.name + ": EOF exception found" )
2704 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002705 main.cleanup()
2706 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002707 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002708 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002709 main.cleanup()
2710 main.exit()
2711
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002713 """
andrewonlab7c211572014-10-15 16:45:20 -04002714 Uses 'nodes' function to obtain list of all nodes
2715 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002716 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002717 Returns:
2718 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002719 """
andrewonlab7c211572014-10-15 16:45:20 -04002720 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002721 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002723 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002724 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002726 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002727 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002728 nodesJson = json.loads( nodesStr )
2729 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002731 except ( TypeError, ValueError ):
2732 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002733 return None
andrewonlab7c211572014-10-15 16:45:20 -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 )
andrewonlab7c211572014-10-15 16:45:20 -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!" )
andrewonlab7c211572014-10-15 16:45:20 -04002741 main.cleanup()
2742 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002743
kelvin-onlabd3b64892015-01-20 13:26:24 -08002744 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002745 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002746 Return the first device from the devices api whose 'id' contains 'dpid'
2747 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002748 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002749 try:
kelvin8ec71442015-01-15 16:57:00 -08002750 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002751 return None
2752 else:
kelvin8ec71442015-01-15 16:57:00 -08002753 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 rawDevices = self.devices()
2755 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002756 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002758 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2759 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002760 return device
2761 return None
Jon Hallc6793552016-01-19 14:18:37 -08002762 except ( TypeError, ValueError ):
2763 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002764 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002768 main.cleanup()
2769 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002772 main.cleanup()
2773 main.exit()
2774
You Wang24139872016-05-03 11:48:47 -07002775 def getTopology( self, topologyOutput ):
2776 """
2777 Definition:
2778 Loads a json topology output
2779 Return:
2780 topology = current ONOS topology
2781 """
2782 import json
2783 try:
2784 # either onos:topology or 'topology' will work in CLI
2785 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002786 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002787 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002788 except ( TypeError, ValueError ):
2789 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2790 return None
You Wang24139872016-05-03 11:48:47 -07002791 except pexpect.EOF:
2792 main.log.error( self.name + ": EOF exception found" )
2793 main.log.error( self.name + ": " + self.handle.before )
2794 main.cleanup()
2795 main.exit()
2796 except Exception:
2797 main.log.exception( self.name + ": Uncaught exception!" )
2798 main.cleanup()
2799 main.exit()
2800
Flavio Castro82ee2f62016-06-07 15:04:12 -07002801 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002802 """
Jon Hallefbd9792015-03-05 16:11:36 -08002803 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002804 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002805 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002806
Flavio Castro82ee2f62016-06-07 15:04:12 -07002807 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002808 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002809 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002810 logLevel = level to log to.
2811 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002812
Jon Hallefbd9792015-03-05 16:11:36 -08002813 Returns: main.TRUE if the number of switches and links are correct,
2814 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002815 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002816 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002817 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002818 try:
You Wang13310252016-07-31 10:56:14 -07002819 summary = self.summary()
2820 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002821 except ( TypeError, ValueError ):
2822 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2823 return main.ERROR
2824 try:
2825 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002826 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002827 return main.ERROR
2828 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002829 # Is the number of switches is what we expected
2830 devices = topology.get( 'devices', False )
2831 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002832 nodes = summary.get( 'nodes', False )
2833 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002834 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002835 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002836 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002837 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002838 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2839 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002840 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002841 output = output + "The number of links and switches match "\
2842 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002843 result = main.TRUE
2844 else:
You Wang24139872016-05-03 11:48:47 -07002845 output = output + \
2846 "The number of links and switches does not match " + \
2847 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002848 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002849 output = output + "\n ONOS sees %i devices" % int( devices )
2850 output = output + " (%i expected) " % int( numoswitch )
2851 output = output + "and %i links " % int( links )
2852 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002853 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002854 output = output + "and %i controllers " % int( nodes )
2855 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002857 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002858 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002859 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002860 else:
You Wang24139872016-05-03 11:48:47 -07002861 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002862 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002863 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002864 main.log.error( self.name + ": EOF exception found" )
2865 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002866 main.cleanup()
2867 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002868 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002869 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002870 main.cleanup()
2871 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002872
kelvin-onlabd3b64892015-01-20 13:26:24 -08002873 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002874 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002875 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002876 deviceId must be the id of a device as seen in the onos devices command
2877 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002878 role must be either master, standby, or none
2879
Jon Halle3f39ff2015-01-13 11:50:53 -08002880 Returns:
2881 main.TRUE or main.FALSE based on argument verification and
2882 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002883 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002884 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002885 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002886 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002887 cmdStr = "device-role " +\
2888 str( deviceId ) + " " +\
2889 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002890 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002892 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002893 if re.search( "Error", handle ):
2894 # end color output to escape any colours
2895 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002896 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002897 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002898 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002899 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002900 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002901 main.log.error( "Invalid 'role' given to device_role(). " +
2902 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002903 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002904 except AssertionError:
2905 main.log.exception( "" )
2906 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002907 except TypeError:
2908 main.log.exception( self.name + ": Object not as expected" )
2909 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002911 main.log.error( self.name + ": EOF exception found" )
2912 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002913 main.cleanup()
2914 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002915 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002916 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002917 main.cleanup()
2918 main.exit()
2919
kelvin-onlabd3b64892015-01-20 13:26:24 -08002920 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002921 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002922 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002923 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002924 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002925 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002926 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002927 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002928 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002929 cmdStr += " -j"
2930 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002931 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002932 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002933 except AssertionError:
2934 main.log.exception( "" )
2935 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002936 except TypeError:
2937 main.log.exception( self.name + ": Object not as expected" )
2938 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002939 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002940 main.log.error( self.name + ": EOF exception found" )
2941 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002942 main.cleanup()
2943 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002944 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002945 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002946 main.cleanup()
2947 main.exit()
2948
kelvin-onlabd3b64892015-01-20 13:26:24 -08002949 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002950 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002951 CLI command to get the current leader for the Election test application
2952 NOTE: Requires installation of the onos-app-election feature
2953 Returns: Node IP of the leader if one exists
2954 None if none exists
2955 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002956 """
Jon Hall94fd0472014-12-08 11:52:42 -08002957 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002958 cmdStr = "election-test-leader"
2959 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002960 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002961 # Leader
2962 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002963 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002964 nodeSearch = re.search( leaderPattern, response )
2965 if nodeSearch:
2966 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002967 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002968 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002969 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002970 # no leader
2971 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002972 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002973 nullSearch = re.search( nullPattern, response )
2974 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002975 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002976 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002977 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002978 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07002979 main.log.error( "Error in electionTestLeader on " + self.name +
2980 ": " + "unexpected response" )
2981 main.log.error( repr( response ) )
2982 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002983 except AssertionError:
2984 main.log.exception( "" )
2985 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002986 except TypeError:
2987 main.log.exception( self.name + ": Object not as expected" )
2988 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002989 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002990 main.log.error( self.name + ": EOF exception found" )
2991 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002992 main.cleanup()
2993 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002994 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002995 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002996 main.cleanup()
2997 main.exit()
2998
kelvin-onlabd3b64892015-01-20 13:26:24 -08002999 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003000 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003001 CLI command to run for leadership of the Election test application.
3002 NOTE: Requires installation of the onos-app-election feature
3003 Returns: Main.TRUE on success
3004 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 """
Jon Hall94fd0472014-12-08 11:52:42 -08003006 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003007 cmdStr = "election-test-run"
3008 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003009 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003010 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003011 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003012 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003013 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003014 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003015 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003016 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003017 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003018 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003019 main.log.error( "Error in electionTestRun on " + self.name +
3020 ": " + "unexpected response" )
3021 main.log.error( repr( response ) )
3022 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003023 except AssertionError:
3024 main.log.exception( "" )
3025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003026 except TypeError:
3027 main.log.exception( self.name + ": Object not as expected" )
3028 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003030 main.log.error( self.name + ": EOF exception found" )
3031 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003032 main.cleanup()
3033 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003034 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003035 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003036 main.cleanup()
3037 main.exit()
3038
kelvin-onlabd3b64892015-01-20 13:26:24 -08003039 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003040 """
Jon Hall94fd0472014-12-08 11:52:42 -08003041 * CLI command to withdraw the local node from leadership election for
3042 * the Election test application.
3043 #NOTE: Requires installation of the onos-app-election feature
3044 Returns: Main.TRUE on success
3045 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003046 """
Jon Hall94fd0472014-12-08 11:52:42 -08003047 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003048 cmdStr = "election-test-withdraw"
3049 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003050 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003051 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003052 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003053 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003054 if re.search( successPattern, response ):
3055 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003056 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003057 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003058 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003059 main.log.error( "Error in electionTestWithdraw on " +
3060 self.name + ": " + "unexpected response" )
3061 main.log.error( repr( response ) )
3062 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003063 except AssertionError:
3064 main.log.exception( "" )
3065 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003066 except TypeError:
3067 main.log.exception( self.name + ": Object not as expected" )
3068 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003070 main.log.error( self.name + ": EOF exception found" )
3071 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003072 main.cleanup()
3073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003075 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003076 main.cleanup()
3077 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003078
kelvin8ec71442015-01-15 16:57:00 -08003079 def getDevicePortsEnabledCount( self, dpid ):
3080 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003081 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003082 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003083 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003084 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003085 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3086 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003087 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003088 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003089 if re.search( "No such device", output ):
3090 main.log.error( "Error in getting ports" )
3091 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003092 return output
Jon Hallc6793552016-01-19 14:18:37 -08003093 except AssertionError:
3094 main.log.exception( "" )
3095 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003096 except TypeError:
3097 main.log.exception( self.name + ": Object not as expected" )
3098 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003102 main.cleanup()
3103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003105 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003106 main.cleanup()
3107 main.exit()
3108
kelvin8ec71442015-01-15 16:57:00 -08003109 def getDeviceLinksActiveCount( self, dpid ):
3110 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003111 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003112 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003113 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003114 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003115 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3116 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003117 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003118 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003119 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003120 main.log.error( "Error in getting ports " )
3121 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003122 return output
Jon Hallc6793552016-01-19 14:18:37 -08003123 except AssertionError:
3124 main.log.exception( "" )
3125 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003126 except TypeError:
3127 main.log.exception( self.name + ": Object not as expected" )
3128 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003130 main.log.error( self.name + ": EOF exception found" )
3131 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 main.cleanup()
3133 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003134 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003135 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003136 main.cleanup()
3137 main.exit()
3138
kelvin8ec71442015-01-15 16:57:00 -08003139 def getAllIntentIds( self ):
3140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003142 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003144 cmdStr = "onos:intents | grep id="
3145 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003146 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003147 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003148 if re.search( "Error", output ):
3149 main.log.error( "Error in getting ports" )
3150 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003151 return output
Jon Hallc6793552016-01-19 14:18:37 -08003152 except AssertionError:
3153 main.log.exception( "" )
3154 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003155 except TypeError:
3156 main.log.exception( self.name + ": Object not as expected" )
3157 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003158 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003159 main.log.error( self.name + ": EOF exception found" )
3160 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003161 main.cleanup()
3162 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003163 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003164 main.log.exception( self.name + ": Uncaught exception!" )
3165 main.cleanup()
3166 main.exit()
3167
Jon Hall73509952015-02-24 16:42:56 -08003168 def intentSummary( self ):
3169 """
Jon Hallefbd9792015-03-05 16:11:36 -08003170 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003171 """
3172 try:
3173 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003174 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003175 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003176 states.append( intent.get( 'state', None ) )
3177 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003178 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003179 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003180 except ( TypeError, ValueError ):
3181 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003182 return None
3183 except pexpect.EOF:
3184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
3186 main.cleanup()
3187 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003188 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003189 main.log.exception( self.name + ": Uncaught exception!" )
3190 main.cleanup()
3191 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003192
Jon Hall61282e32015-03-19 11:34:11 -07003193 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003194 """
3195 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003196 Optional argument:
3197 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003198 """
Jon Hall63604932015-02-26 17:09:50 -08003199 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003200 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003201 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003202 cmdStr += " -j"
3203 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003204 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003205 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003206 return output
Jon Hallc6793552016-01-19 14:18:37 -08003207 except AssertionError:
3208 main.log.exception( "" )
3209 return None
Jon Hall63604932015-02-26 17:09:50 -08003210 except TypeError:
3211 main.log.exception( self.name + ": Object not as expected" )
3212 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003213 except pexpect.EOF:
3214 main.log.error( self.name + ": EOF exception found" )
3215 main.log.error( self.name + ": " + self.handle.before )
3216 main.cleanup()
3217 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003218 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003219 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003220 main.cleanup()
3221 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003222
acsmarsa4a4d1e2015-07-10 16:01:24 -07003223 def leaderCandidates( self, jsonFormat=True ):
3224 """
3225 Returns the output of the leaders -c command.
3226 Optional argument:
3227 * jsonFormat - boolean indicating if you want output in json
3228 """
3229 try:
3230 cmdStr = "onos:leaders -c"
3231 if jsonFormat:
3232 cmdStr += " -j"
3233 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003234 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003235 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003236 return output
Jon Hallc6793552016-01-19 14:18:37 -08003237 except AssertionError:
3238 main.log.exception( "" )
3239 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003240 except TypeError:
3241 main.log.exception( self.name + ": Object not as expected" )
3242 return None
3243 except pexpect.EOF:
3244 main.log.error( self.name + ": EOF exception found" )
3245 main.log.error( self.name + ": " + self.handle.before )
3246 main.cleanup()
3247 main.exit()
3248 except Exception:
3249 main.log.exception( self.name + ": Uncaught exception!" )
3250 main.cleanup()
3251 main.exit()
3252
Jon Hallc6793552016-01-19 14:18:37 -08003253 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003254 """
3255 Returns a list in format [leader,candidate1,candidate2,...] for a given
3256 topic parameter and an empty list if the topic doesn't exist
3257 If no leader is elected leader in the returned list will be "none"
3258 Returns None if there is a type error processing the json object
3259 """
3260 try:
Jon Hall6e709752016-02-01 13:38:46 -08003261 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003262 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003263 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003264 assert "Command not found:" not in rawOutput, rawOutput
3265 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003266 results = []
3267 for dict in output:
3268 if dict["topic"] == topic:
3269 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003270 candidates = re.split( ", ", dict["candidates"][1:-1] )
3271 results.append( leader )
3272 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003273 return results
Jon Hallc6793552016-01-19 14:18:37 -08003274 except AssertionError:
3275 main.log.exception( "" )
3276 return None
3277 except ( TypeError, ValueError ):
3278 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003279 return None
3280 except pexpect.EOF:
3281 main.log.error( self.name + ": EOF exception found" )
3282 main.log.error( self.name + ": " + self.handle.before )
3283 main.cleanup()
3284 main.exit()
3285 except Exception:
3286 main.log.exception( self.name + ": Uncaught exception!" )
3287 main.cleanup()
3288 main.exit()
3289
Jon Hall61282e32015-03-19 11:34:11 -07003290 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003291 """
3292 Returns the output of the intent Pending map.
3293 """
Jon Hall63604932015-02-26 17:09:50 -08003294 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003295 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003296 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003297 cmdStr += " -j"
3298 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003299 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003300 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003301 return output
Jon Hallc6793552016-01-19 14:18:37 -08003302 except AssertionError:
3303 main.log.exception( "" )
3304 return None
Jon Hall63604932015-02-26 17:09:50 -08003305 except TypeError:
3306 main.log.exception( self.name + ": Object not as expected" )
3307 return None
3308 except pexpect.EOF:
3309 main.log.error( self.name + ": EOF exception found" )
3310 main.log.error( self.name + ": " + self.handle.before )
3311 main.cleanup()
3312 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003313 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003314 main.log.exception( self.name + ": Uncaught exception!" )
3315 main.cleanup()
3316 main.exit()
3317
Jon Hall61282e32015-03-19 11:34:11 -07003318 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003319 """
3320 Returns the output of the raft partitions command for ONOS.
3321 """
Jon Hall61282e32015-03-19 11:34:11 -07003322 # Sample JSON
3323 # {
3324 # "leader": "tcp://10.128.30.11:7238",
3325 # "members": [
3326 # "tcp://10.128.30.11:7238",
3327 # "tcp://10.128.30.17:7238",
3328 # "tcp://10.128.30.13:7238",
3329 # ],
3330 # "name": "p1",
3331 # "term": 3
3332 # },
Jon Hall63604932015-02-26 17:09:50 -08003333 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003334 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003335 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003336 cmdStr += " -j"
3337 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003338 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003339 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003340 return output
Jon Hallc6793552016-01-19 14:18:37 -08003341 except AssertionError:
3342 main.log.exception( "" )
3343 return None
Jon Hall63604932015-02-26 17:09:50 -08003344 except TypeError:
3345 main.log.exception( self.name + ": Object not as expected" )
3346 return None
3347 except pexpect.EOF:
3348 main.log.error( self.name + ": EOF exception found" )
3349 main.log.error( self.name + ": " + self.handle.before )
3350 main.cleanup()
3351 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003352 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003353 main.log.exception( self.name + ": Uncaught exception!" )
3354 main.cleanup()
3355 main.exit()
3356
Jon Hallbe379602015-03-24 13:39:32 -07003357 def apps( self, jsonFormat=True ):
3358 """
3359 Returns the output of the apps command for ONOS. This command lists
3360 information about installed ONOS applications
3361 """
3362 # Sample JSON object
3363 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3364 # "description":"ONOS OpenFlow protocol southbound providers",
3365 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3366 # "features":"[onos-openflow]","state":"ACTIVE"}]
3367 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003368 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -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
3374 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003375 return output
Jon Hallbe379602015-03-24 13:39:32 -07003376 # FIXME: look at specific exceptions/Errors
3377 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003378 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003379 return None
3380 except TypeError:
3381 main.log.exception( self.name + ": Object not as expected" )
3382 return None
3383 except pexpect.EOF:
3384 main.log.error( self.name + ": EOF exception found" )
3385 main.log.error( self.name + ": " + self.handle.before )
3386 main.cleanup()
3387 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003388 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003389 main.log.exception( self.name + ": Uncaught exception!" )
3390 main.cleanup()
3391 main.exit()
3392
Jon Hall146f1522015-03-24 15:33:24 -07003393 def appStatus( self, appName ):
3394 """
3395 Uses the onos:apps cli command to return the status of an application.
3396 Returns:
3397 "ACTIVE" - If app is installed and activated
3398 "INSTALLED" - If app is installed and deactivated
3399 "UNINSTALLED" - If app is not installed
3400 None - on error
3401 """
Jon Hall146f1522015-03-24 15:33:24 -07003402 try:
3403 if not isinstance( appName, types.StringType ):
3404 main.log.error( self.name + ".appStatus(): appName must be" +
3405 " a string" )
3406 return None
3407 output = self.apps( jsonFormat=True )
3408 appsJson = json.loads( output )
3409 state = None
3410 for app in appsJson:
3411 if appName == app.get('name'):
3412 state = app.get('state')
3413 break
3414 if state == "ACTIVE" or state == "INSTALLED":
3415 return state
3416 elif state is None:
3417 return "UNINSTALLED"
3418 elif state:
3419 main.log.error( "Unexpected state from 'onos:apps': " +
3420 str( state ) )
3421 return state
Jon Hallc6793552016-01-19 14:18:37 -08003422 except ( TypeError, ValueError ):
3423 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003424 return None
3425 except pexpect.EOF:
3426 main.log.error( self.name + ": EOF exception found" )
3427 main.log.error( self.name + ": " + self.handle.before )
3428 main.cleanup()
3429 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003430 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003431 main.log.exception( self.name + ": Uncaught exception!" )
3432 main.cleanup()
3433 main.exit()
3434
Jon Hallbe379602015-03-24 13:39:32 -07003435 def app( self, appName, option ):
3436 """
3437 Interacts with the app command for ONOS. This command manages
3438 application inventory.
3439 """
Jon Hallbe379602015-03-24 13:39:32 -07003440 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003441 # Validate argument types
3442 valid = True
3443 if not isinstance( appName, types.StringType ):
3444 main.log.error( self.name + ".app(): appName must be a " +
3445 "string" )
3446 valid = False
3447 if not isinstance( option, types.StringType ):
3448 main.log.error( self.name + ".app(): option must be a string" )
3449 valid = False
3450 if not valid:
3451 return main.FALSE
3452 # Validate Option
3453 option = option.lower()
3454 # NOTE: Install may become a valid option
3455 if option == "activate":
3456 pass
3457 elif option == "deactivate":
3458 pass
3459 elif option == "uninstall":
3460 pass
3461 else:
3462 # Invalid option
3463 main.log.error( "The ONOS app command argument only takes " +
3464 "the values: (activate|deactivate|uninstall)" +
3465 "; was given '" + option + "'")
3466 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003467 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003468 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003469 if "Error executing command" in output:
3470 main.log.error( "Error in processing onos:app command: " +
3471 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003472 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003473 elif "No such application" in output:
3474 main.log.error( "The application '" + appName +
3475 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003476 return main.FALSE
3477 elif "Command not found:" in output:
3478 main.log.error( "Error in processing onos:app command: " +
3479 str( output ) )
3480 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003481 elif "Unsupported command:" in output:
3482 main.log.error( "Incorrect command given to 'app': " +
3483 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003484 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003485 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003486 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003487 return main.TRUE
3488 except TypeError:
3489 main.log.exception( self.name + ": Object not as expected" )
3490 return main.ERROR
3491 except pexpect.EOF:
3492 main.log.error( self.name + ": EOF exception found" )
3493 main.log.error( self.name + ": " + self.handle.before )
3494 main.cleanup()
3495 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003496 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003497 main.log.exception( self.name + ": Uncaught exception!" )
3498 main.cleanup()
3499 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003500
Jon Hallbd16b922015-03-26 17:53:15 -07003501 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003502 """
3503 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003504 appName is the hierarchical app name, not the feature name
3505 If check is True, method will check the status of the app after the
3506 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003507 Returns main.TRUE if the command was successfully sent
3508 main.FALSE if the cli responded with an error or given
3509 incorrect input
3510 """
3511 try:
3512 if not isinstance( appName, types.StringType ):
3513 main.log.error( self.name + ".activateApp(): appName must be" +
3514 " a string" )
3515 return main.FALSE
3516 status = self.appStatus( appName )
3517 if status == "INSTALLED":
3518 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003519 if check and response == main.TRUE:
3520 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003521 status = self.appStatus( appName )
3522 if status == "ACTIVE":
3523 return main.TRUE
3524 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003525 main.log.debug( "The state of application " +
3526 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003527 time.sleep( 1 )
3528 return main.FALSE
3529 else: # not 'check' or command didn't succeed
3530 return response
Jon Hall146f1522015-03-24 15:33:24 -07003531 elif status == "ACTIVE":
3532 return main.TRUE
3533 elif status == "UNINSTALLED":
3534 main.log.error( self.name + ": Tried to activate the " +
3535 "application '" + appName + "' which is not " +
3536 "installed." )
3537 else:
3538 main.log.error( "Unexpected return value from appStatus: " +
3539 str( status ) )
3540 return main.ERROR
3541 except TypeError:
3542 main.log.exception( self.name + ": Object not as expected" )
3543 return main.ERROR
3544 except pexpect.EOF:
3545 main.log.error( self.name + ": EOF exception found" )
3546 main.log.error( self.name + ": " + self.handle.before )
3547 main.cleanup()
3548 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003549 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003550 main.log.exception( self.name + ": Uncaught exception!" )
3551 main.cleanup()
3552 main.exit()
3553
Jon Hallbd16b922015-03-26 17:53:15 -07003554 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003555 """
3556 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003557 appName is the hierarchical app name, not the feature name
3558 If check is True, method will check the status of the app after the
3559 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003560 Returns main.TRUE if the command was successfully sent
3561 main.FALSE if the cli responded with an error or given
3562 incorrect input
3563 """
3564 try:
3565 if not isinstance( appName, types.StringType ):
3566 main.log.error( self.name + ".deactivateApp(): appName must " +
3567 "be a string" )
3568 return main.FALSE
3569 status = self.appStatus( appName )
3570 if status == "INSTALLED":
3571 return main.TRUE
3572 elif status == "ACTIVE":
3573 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003574 if check and response == main.TRUE:
3575 for i in range(10): # try 10 times then give up
3576 status = self.appStatus( appName )
3577 if status == "INSTALLED":
3578 return main.TRUE
3579 else:
3580 time.sleep( 1 )
3581 return main.FALSE
3582 else: # not check or command didn't succeed
3583 return response
Jon Hall146f1522015-03-24 15:33:24 -07003584 elif status == "UNINSTALLED":
3585 main.log.warn( self.name + ": Tried to deactivate the " +
3586 "application '" + appName + "' which is not " +
3587 "installed." )
3588 return main.TRUE
3589 else:
3590 main.log.error( "Unexpected return value from appStatus: " +
3591 str( status ) )
3592 return main.ERROR
3593 except TypeError:
3594 main.log.exception( self.name + ": Object not as expected" )
3595 return main.ERROR
3596 except pexpect.EOF:
3597 main.log.error( self.name + ": EOF exception found" )
3598 main.log.error( self.name + ": " + self.handle.before )
3599 main.cleanup()
3600 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003601 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003602 main.log.exception( self.name + ": Uncaught exception!" )
3603 main.cleanup()
3604 main.exit()
3605
Jon Hallbd16b922015-03-26 17:53:15 -07003606 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003607 """
3608 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003609 appName is the hierarchical app name, not the feature name
3610 If check is True, method will check the status of the app after the
3611 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003612 Returns main.TRUE if the command was successfully sent
3613 main.FALSE if the cli responded with an error or given
3614 incorrect input
3615 """
3616 # TODO: check with Thomas about the state machine for apps
3617 try:
3618 if not isinstance( appName, types.StringType ):
3619 main.log.error( self.name + ".uninstallApp(): appName must " +
3620 "be a string" )
3621 return main.FALSE
3622 status = self.appStatus( appName )
3623 if status == "INSTALLED":
3624 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003625 if check and response == main.TRUE:
3626 for i in range(10): # try 10 times then give up
3627 status = self.appStatus( appName )
3628 if status == "UNINSTALLED":
3629 return main.TRUE
3630 else:
3631 time.sleep( 1 )
3632 return main.FALSE
3633 else: # not check or command didn't succeed
3634 return response
Jon Hall146f1522015-03-24 15:33:24 -07003635 elif status == "ACTIVE":
3636 main.log.warn( self.name + ": Tried to uninstall the " +
3637 "application '" + appName + "' which is " +
3638 "currently active." )
3639 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003640 if check and response == main.TRUE:
3641 for i in range(10): # try 10 times then give up
3642 status = self.appStatus( appName )
3643 if status == "UNINSTALLED":
3644 return main.TRUE
3645 else:
3646 time.sleep( 1 )
3647 return main.FALSE
3648 else: # not check or command didn't succeed
3649 return response
Jon Hall146f1522015-03-24 15:33:24 -07003650 elif status == "UNINSTALLED":
3651 return main.TRUE
3652 else:
3653 main.log.error( "Unexpected return value from appStatus: " +
3654 str( status ) )
3655 return main.ERROR
3656 except TypeError:
3657 main.log.exception( self.name + ": Object not as expected" )
3658 return main.ERROR
3659 except pexpect.EOF:
3660 main.log.error( self.name + ": EOF exception found" )
3661 main.log.error( self.name + ": " + self.handle.before )
3662 main.cleanup()
3663 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003664 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003665 main.log.exception( self.name + ": Uncaught exception!" )
3666 main.cleanup()
3667 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003668
3669 def appIDs( self, jsonFormat=True ):
3670 """
3671 Show the mappings between app id and app names given by the 'app-ids'
3672 cli command
3673 """
3674 try:
3675 cmdStr = "app-ids"
3676 if jsonFormat:
3677 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003678 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003679 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003680 assert "Command not found:" not in output, output
3681 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003682 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003683 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003684 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003685 return None
3686 except TypeError:
3687 main.log.exception( self.name + ": Object not as expected" )
3688 return None
3689 except pexpect.EOF:
3690 main.log.error( self.name + ": EOF exception found" )
3691 main.log.error( self.name + ": " + self.handle.before )
3692 main.cleanup()
3693 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003694 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003695 main.log.exception( self.name + ": Uncaught exception!" )
3696 main.cleanup()
3697 main.exit()
3698
3699 def appToIDCheck( self ):
3700 """
3701 This method will check that each application's ID listed in 'apps' is
3702 the same as the ID listed in 'app-ids'. The check will also check that
3703 there are no duplicate IDs issued. Note that an app ID should be
3704 a globaly unique numerical identifier for app/app-like features. Once
3705 an ID is registered, the ID is never freed up so that if an app is
3706 reinstalled it will have the same ID.
3707
3708 Returns: main.TRUE if the check passes and
3709 main.FALSE if the check fails or
3710 main.ERROR if there is some error in processing the test
3711 """
3712 try:
Jon Hall390696c2015-05-05 17:13:41 -07003713 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003714 rawJson = self.appIDs( jsonFormat=True )
3715 if rawJson:
3716 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003717 else:
Jon Hallc6793552016-01-19 14:18:37 -08003718 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003719 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003720 rawJson = self.apps( jsonFormat=True )
3721 if rawJson:
3722 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003723 else:
Jon Hallc6793552016-01-19 14:18:37 -08003724 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003725 bail = True
3726 if bail:
3727 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003728 result = main.TRUE
3729 for app in apps:
3730 appID = app.get( 'id' )
3731 if appID is None:
3732 main.log.error( "Error parsing app: " + str( app ) )
3733 result = main.FALSE
3734 appName = app.get( 'name' )
3735 if appName is None:
3736 main.log.error( "Error parsing app: " + str( app ) )
3737 result = main.FALSE
3738 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003739 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003740 # main.log.debug( "Comparing " + str( app ) + " to " +
3741 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003742 if not current: # if ids doesn't have this id
3743 result = main.FALSE
3744 main.log.error( "'app-ids' does not have the ID for " +
3745 str( appName ) + " that apps does." )
3746 elif len( current ) > 1:
3747 # there is more than one app with this ID
3748 result = main.FALSE
3749 # We will log this later in the method
3750 elif not current[0][ 'name' ] == appName:
3751 currentName = current[0][ 'name' ]
3752 result = main.FALSE
3753 main.log.error( "'app-ids' has " + str( currentName ) +
3754 " registered under id:" + str( appID ) +
3755 " but 'apps' has " + str( appName ) )
3756 else:
3757 pass # id and name match!
3758 # now make sure that app-ids has no duplicates
3759 idsList = []
3760 namesList = []
3761 for item in ids:
3762 idsList.append( item[ 'id' ] )
3763 namesList.append( item[ 'name' ] )
3764 if len( idsList ) != len( set( idsList ) ) or\
3765 len( namesList ) != len( set( namesList ) ):
3766 main.log.error( "'app-ids' has some duplicate entries: \n"
3767 + json.dumps( ids,
3768 sort_keys=True,
3769 indent=4,
3770 separators=( ',', ': ' ) ) )
3771 result = main.FALSE
3772 return result
Jon Hallc6793552016-01-19 14:18:37 -08003773 except ( TypeError, ValueError ):
3774 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003775 return main.ERROR
3776 except pexpect.EOF:
3777 main.log.error( self.name + ": EOF exception found" )
3778 main.log.error( self.name + ": " + self.handle.before )
3779 main.cleanup()
3780 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003781 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003782 main.log.exception( self.name + ": Uncaught exception!" )
3783 main.cleanup()
3784 main.exit()
3785
Jon Hallfb760a02015-04-13 15:35:03 -07003786 def getCfg( self, component=None, propName=None, short=False,
3787 jsonFormat=True ):
3788 """
3789 Get configuration settings from onos cli
3790 Optional arguments:
3791 component - Optionally only list configurations for a specific
3792 component. If None, all components with configurations
3793 are displayed. Case Sensitive string.
3794 propName - If component is specified, propName option will show
3795 only this specific configuration from that component.
3796 Case Sensitive string.
3797 jsonFormat - Returns output as json. Note that this will override
3798 the short option
3799 short - Short, less verbose, version of configurations.
3800 This is overridden by the json option
3801 returns:
3802 Output from cli as a string or None on error
3803 """
3804 try:
3805 baseStr = "cfg"
3806 cmdStr = " get"
3807 componentStr = ""
3808 if component:
3809 componentStr += " " + component
3810 if propName:
3811 componentStr += " " + propName
3812 if jsonFormat:
3813 baseStr += " -j"
3814 elif short:
3815 baseStr += " -s"
3816 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003817 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003818 assert "Command not found:" not in output, output
3819 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003820 return output
3821 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003822 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003823 return None
3824 except TypeError:
3825 main.log.exception( self.name + ": Object not as expected" )
3826 return None
3827 except pexpect.EOF:
3828 main.log.error( self.name + ": EOF exception found" )
3829 main.log.error( self.name + ": " + self.handle.before )
3830 main.cleanup()
3831 main.exit()
3832 except Exception:
3833 main.log.exception( self.name + ": Uncaught exception!" )
3834 main.cleanup()
3835 main.exit()
3836
3837 def setCfg( self, component, propName, value=None, check=True ):
3838 """
3839 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003840 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003841 component - The case sensitive name of the component whose
3842 property is to be set
3843 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003844 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003845 value - The value to set the property to. If None, will unset the
3846 property and revert it to it's default value(if applicable)
3847 check - Boolean, Check whether the option was successfully set this
3848 only applies when a value is given.
3849 returns:
3850 main.TRUE on success or main.FALSE on failure. If check is False,
3851 will return main.TRUE unless there is an error
3852 """
3853 try:
3854 baseStr = "cfg"
3855 cmdStr = " set " + str( component ) + " " + str( propName )
3856 if value is not None:
3857 cmdStr += " " + str( value )
3858 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003859 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003860 assert "Command not found:" not in output, output
3861 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003862 if value and check:
3863 results = self.getCfg( component=str( component ),
3864 propName=str( propName ),
3865 jsonFormat=True )
3866 # Check if current value is what we just set
3867 try:
3868 jsonOutput = json.loads( results )
3869 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003870 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003871 main.log.exception( "Error parsing cfg output" )
3872 main.log.error( "output:" + repr( results ) )
3873 return main.FALSE
3874 if current == str( value ):
3875 return main.TRUE
3876 return main.FALSE
3877 return main.TRUE
3878 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003879 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003880 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003881 except ( TypeError, ValueError ):
3882 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003883 return main.FALSE
3884 except pexpect.EOF:
3885 main.log.error( self.name + ": EOF exception found" )
3886 main.log.error( self.name + ": " + self.handle.before )
3887 main.cleanup()
3888 main.exit()
3889 except Exception:
3890 main.log.exception( self.name + ": Uncaught exception!" )
3891 main.cleanup()
3892 main.exit()
3893
Jon Hall390696c2015-05-05 17:13:41 -07003894 def setTestAdd( self, setName, values ):
3895 """
3896 CLI command to add elements to a distributed set.
3897 Arguments:
3898 setName - The name of the set to add to.
3899 values - The value(s) to add to the set, space seperated.
3900 Example usages:
3901 setTestAdd( "set1", "a b c" )
3902 setTestAdd( "set2", "1" )
3903 returns:
3904 main.TRUE on success OR
3905 main.FALSE if elements were already in the set OR
3906 main.ERROR on error
3907 """
3908 try:
3909 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3910 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003911 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003912 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003913 try:
3914 # TODO: Maybe make this less hardcoded
3915 # ConsistentMap Exceptions
3916 assert "org.onosproject.store.service" not in output
3917 # Node not leader
3918 assert "java.lang.IllegalStateException" not in output
3919 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003920 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003921 "command: " + str( output ) )
3922 retryTime = 30 # Conservative time, given by Madan
3923 main.log.info( "Waiting " + str( retryTime ) +
3924 "seconds before retrying." )
3925 time.sleep( retryTime ) # Due to change in mastership
3926 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003927 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003928 assert "Error executing command" not in output
3929 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3930 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3931 main.log.info( self.name + ": " + output )
3932 if re.search( positiveMatch, output):
3933 return main.TRUE
3934 elif re.search( negativeMatch, output):
3935 return main.FALSE
3936 else:
3937 main.log.error( self.name + ": setTestAdd did not" +
3938 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003939 main.log.debug( self.name + " actual: " + repr( output ) )
3940 return main.ERROR
3941 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003942 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003943 return main.ERROR
3944 except TypeError:
3945 main.log.exception( self.name + ": Object not as expected" )
3946 return main.ERROR
3947 except pexpect.EOF:
3948 main.log.error( self.name + ": EOF exception found" )
3949 main.log.error( self.name + ": " + self.handle.before )
3950 main.cleanup()
3951 main.exit()
3952 except Exception:
3953 main.log.exception( self.name + ": Uncaught exception!" )
3954 main.cleanup()
3955 main.exit()
3956
3957 def setTestRemove( self, setName, values, clear=False, retain=False ):
3958 """
3959 CLI command to remove elements from a distributed set.
3960 Required arguments:
3961 setName - The name of the set to remove from.
3962 values - The value(s) to remove from the set, space seperated.
3963 Optional arguments:
3964 clear - Clear all elements from the set
3965 retain - Retain only the given values. (intersection of the
3966 original set and the given set)
3967 returns:
3968 main.TRUE on success OR
3969 main.FALSE if the set was not changed OR
3970 main.ERROR on error
3971 """
3972 try:
3973 cmdStr = "set-test-remove "
3974 if clear:
3975 cmdStr += "-c " + str( setName )
3976 elif retain:
3977 cmdStr += "-r " + str( setName ) + " " + str( values )
3978 else:
3979 cmdStr += str( setName ) + " " + str( values )
3980 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003981 try:
Jon Halla495f562016-05-16 18:03:26 -07003982 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003983 # TODO: Maybe make this less hardcoded
3984 # ConsistentMap Exceptions
3985 assert "org.onosproject.store.service" not in output
3986 # Node not leader
3987 assert "java.lang.IllegalStateException" not in output
3988 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003989 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003990 "command: " + str( output ) )
3991 retryTime = 30 # Conservative time, given by Madan
3992 main.log.info( "Waiting " + str( retryTime ) +
3993 "seconds before retrying." )
3994 time.sleep( retryTime ) # Due to change in mastership
3995 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003996 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003997 assert "Command not found:" not in output, output
3998 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003999 main.log.info( self.name + ": " + output )
4000 if clear:
4001 pattern = "Set " + str( setName ) + " cleared"
4002 if re.search( pattern, output ):
4003 return main.TRUE
4004 elif retain:
4005 positivePattern = str( setName ) + " was pruned to contain " +\
4006 "only elements of set \[(.*)\]"
4007 negativePattern = str( setName ) + " was not changed by " +\
4008 "retaining only elements of the set " +\
4009 "\[(.*)\]"
4010 if re.search( positivePattern, output ):
4011 return main.TRUE
4012 elif re.search( negativePattern, output ):
4013 return main.FALSE
4014 else:
4015 positivePattern = "\[(.*)\] was removed from the set " +\
4016 str( setName )
4017 if ( len( values.split() ) == 1 ):
4018 negativePattern = "\[(.*)\] was not in set " +\
4019 str( setName )
4020 else:
4021 negativePattern = "No element of \[(.*)\] was in set " +\
4022 str( setName )
4023 if re.search( positivePattern, output ):
4024 return main.TRUE
4025 elif re.search( negativePattern, output ):
4026 return main.FALSE
4027 main.log.error( self.name + ": setTestRemove did not" +
4028 " match expected output" )
4029 main.log.debug( self.name + " expected: " + pattern )
4030 main.log.debug( self.name + " actual: " + repr( output ) )
4031 return main.ERROR
4032 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004033 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004034 return main.ERROR
4035 except TypeError:
4036 main.log.exception( self.name + ": Object not as expected" )
4037 return main.ERROR
4038 except pexpect.EOF:
4039 main.log.error( self.name + ": EOF exception found" )
4040 main.log.error( self.name + ": " + self.handle.before )
4041 main.cleanup()
4042 main.exit()
4043 except Exception:
4044 main.log.exception( self.name + ": Uncaught exception!" )
4045 main.cleanup()
4046 main.exit()
4047
4048 def setTestGet( self, setName, values="" ):
4049 """
4050 CLI command to get the elements in a distributed set.
4051 Required arguments:
4052 setName - The name of the set to remove from.
4053 Optional arguments:
4054 values - The value(s) to check if in the set, space seperated.
4055 returns:
4056 main.ERROR on error OR
4057 A list of elements in the set if no optional arguments are
4058 supplied OR
4059 A tuple containing the list then:
4060 main.FALSE if the given values are not in the set OR
4061 main.TRUE if the given values are in the set OR
4062 """
4063 try:
4064 values = str( values ).strip()
4065 setName = str( setName ).strip()
4066 length = len( values.split() )
4067 containsCheck = None
4068 # Patterns to match
4069 setPattern = "\[(.*)\]"
4070 pattern = "Items in set " + setName + ":\n" + setPattern
4071 containsTrue = "Set " + setName + " contains the value " + values
4072 containsFalse = "Set " + setName + " did not contain the value " +\
4073 values
4074 containsAllTrue = "Set " + setName + " contains the the subset " +\
4075 setPattern
4076 containsAllFalse = "Set " + setName + " did not contain the the" +\
4077 " subset " + setPattern
4078
4079 cmdStr = "set-test-get "
4080 cmdStr += setName + " " + values
4081 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004082 try:
Jon Halla495f562016-05-16 18:03:26 -07004083 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004084 # TODO: Maybe make this less hardcoded
4085 # ConsistentMap Exceptions
4086 assert "org.onosproject.store.service" not in output
4087 # Node not leader
4088 assert "java.lang.IllegalStateException" not in output
4089 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004090 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004091 "command: " + str( output ) )
4092 retryTime = 30 # Conservative time, given by Madan
4093 main.log.info( "Waiting " + str( retryTime ) +
4094 "seconds before retrying." )
4095 time.sleep( retryTime ) # Due to change in mastership
4096 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004097 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004098 assert "Command not found:" not in output, output
4099 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004100 main.log.info( self.name + ": " + output )
4101
4102 if length == 0:
4103 match = re.search( pattern, output )
4104 else: # if given values
4105 if length == 1: # Contains output
4106 patternTrue = pattern + "\n" + containsTrue
4107 patternFalse = pattern + "\n" + containsFalse
4108 else: # ContainsAll output
4109 patternTrue = pattern + "\n" + containsAllTrue
4110 patternFalse = pattern + "\n" + containsAllFalse
4111 matchTrue = re.search( patternTrue, output )
4112 matchFalse = re.search( patternFalse, output )
4113 if matchTrue:
4114 containsCheck = main.TRUE
4115 match = matchTrue
4116 elif matchFalse:
4117 containsCheck = main.FALSE
4118 match = matchFalse
4119 else:
4120 main.log.error( self.name + " setTestGet did not match " +\
4121 "expected output" )
4122 main.log.debug( self.name + " expected: " + pattern )
4123 main.log.debug( self.name + " actual: " + repr( output ) )
4124 match = None
4125 if match:
4126 setMatch = match.group( 1 )
4127 if setMatch == '':
4128 setList = []
4129 else:
4130 setList = setMatch.split( ", " )
4131 if length > 0:
4132 return ( setList, containsCheck )
4133 else:
4134 return setList
4135 else: # no match
4136 main.log.error( self.name + ": setTestGet did not" +
4137 " match expected output" )
4138 main.log.debug( self.name + " expected: " + pattern )
4139 main.log.debug( self.name + " actual: " + repr( output ) )
4140 return main.ERROR
4141 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004142 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004143 return main.ERROR
4144 except TypeError:
4145 main.log.exception( self.name + ": Object not as expected" )
4146 return main.ERROR
4147 except pexpect.EOF:
4148 main.log.error( self.name + ": EOF exception found" )
4149 main.log.error( self.name + ": " + self.handle.before )
4150 main.cleanup()
4151 main.exit()
4152 except Exception:
4153 main.log.exception( self.name + ": Uncaught exception!" )
4154 main.cleanup()
4155 main.exit()
4156
4157 def setTestSize( self, setName ):
4158 """
4159 CLI command to get the elements in a distributed set.
4160 Required arguments:
4161 setName - The name of the set to remove from.
4162 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004163 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004164 None on error
4165 """
4166 try:
4167 # TODO: Should this check against the number of elements returned
4168 # and then return true/false based on that?
4169 setName = str( setName ).strip()
4170 # Patterns to match
4171 setPattern = "\[(.*)\]"
4172 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4173 setPattern
4174 cmdStr = "set-test-get -s "
4175 cmdStr += setName
4176 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004177 try:
Jon Halla495f562016-05-16 18:03:26 -07004178 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004179 # TODO: Maybe make this less hardcoded
4180 # ConsistentMap Exceptions
4181 assert "org.onosproject.store.service" not in output
4182 # Node not leader
4183 assert "java.lang.IllegalStateException" not in output
4184 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004185 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004186 "command: " + str( output ) )
4187 retryTime = 30 # Conservative time, given by Madan
4188 main.log.info( "Waiting " + str( retryTime ) +
4189 "seconds before retrying." )
4190 time.sleep( retryTime ) # Due to change in mastership
4191 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004192 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004193 assert "Command not found:" not in output, output
4194 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004195 main.log.info( self.name + ": " + output )
4196 match = re.search( pattern, output )
4197 if match:
4198 setSize = int( match.group( 1 ) )
4199 setMatch = match.group( 2 )
4200 if len( setMatch.split() ) == setSize:
4201 main.log.info( "The size returned by " + self.name +
4202 " matches the number of elements in " +
4203 "the returned set" )
4204 else:
4205 main.log.error( "The size returned by " + self.name +
4206 " does not match the number of " +
4207 "elements in the returned set." )
4208 return setSize
4209 else: # no match
4210 main.log.error( self.name + ": setTestGet did not" +
4211 " match expected output" )
4212 main.log.debug( self.name + " expected: " + pattern )
4213 main.log.debug( self.name + " actual: " + repr( output ) )
4214 return None
4215 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004216 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004217 return None
Jon Hall390696c2015-05-05 17:13:41 -07004218 except TypeError:
4219 main.log.exception( self.name + ": Object not as expected" )
4220 return None
4221 except pexpect.EOF:
4222 main.log.error( self.name + ": EOF exception found" )
4223 main.log.error( self.name + ": " + self.handle.before )
4224 main.cleanup()
4225 main.exit()
4226 except Exception:
4227 main.log.exception( self.name + ": Uncaught exception!" )
4228 main.cleanup()
4229 main.exit()
4230
Jon Hall80daded2015-05-27 16:07:00 -07004231 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004232 """
4233 Command to list the various counters in the system.
4234 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004235 if jsonFormat, a string of the json object returned by the cli
4236 command
4237 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004238 None on error
4239 """
Jon Hall390696c2015-05-05 17:13:41 -07004240 try:
4241 counters = {}
4242 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004243 if jsonFormat:
4244 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004245 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004246 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004247 assert "Command not found:" not in output, output
4248 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004249 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004250 return output
Jon Hall390696c2015-05-05 17:13:41 -07004251 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004252 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004253 return None
Jon Hall390696c2015-05-05 17:13:41 -07004254 except TypeError:
4255 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004256 return None
Jon Hall390696c2015-05-05 17:13:41 -07004257 except pexpect.EOF:
4258 main.log.error( self.name + ": EOF exception found" )
4259 main.log.error( self.name + ": " + self.handle.before )
4260 main.cleanup()
4261 main.exit()
4262 except Exception:
4263 main.log.exception( self.name + ": Uncaught exception!" )
4264 main.cleanup()
4265 main.exit()
4266
Jon Hall935db192016-04-19 00:22:04 -07004267 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004268 """
Jon Halle1a3b752015-07-22 13:02:46 -07004269 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004270 Required arguments:
4271 counter - The name of the counter to increment.
4272 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004273 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004274 returns:
4275 integer value of the counter or
4276 None on Error
4277 """
4278 try:
4279 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004280 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004281 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004282 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004283 if delta != 1:
4284 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004285 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004286 try:
Jon Halla495f562016-05-16 18:03:26 -07004287 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004288 # TODO: Maybe make this less hardcoded
4289 # ConsistentMap Exceptions
4290 assert "org.onosproject.store.service" not in output
4291 # Node not leader
4292 assert "java.lang.IllegalStateException" not in output
4293 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004294 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004295 "command: " + str( output ) )
4296 retryTime = 30 # Conservative time, given by Madan
4297 main.log.info( "Waiting " + str( retryTime ) +
4298 "seconds before retrying." )
4299 time.sleep( retryTime ) # Due to change in mastership
4300 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004301 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004302 assert "Command not found:" not in output, output
4303 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004304 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004305 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004306 match = re.search( pattern, output )
4307 if match:
4308 return int( match.group( 1 ) )
4309 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004310 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004311 " match expected output." )
4312 main.log.debug( self.name + " expected: " + pattern )
4313 main.log.debug( self.name + " actual: " + repr( output ) )
4314 return None
4315 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004316 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004317 return None
4318 except TypeError:
4319 main.log.exception( self.name + ": Object not as expected" )
4320 return None
4321 except pexpect.EOF:
4322 main.log.error( self.name + ": EOF exception found" )
4323 main.log.error( self.name + ": " + self.handle.before )
4324 main.cleanup()
4325 main.exit()
4326 except Exception:
4327 main.log.exception( self.name + ": Uncaught exception!" )
4328 main.cleanup()
4329 main.exit()
4330
Jon Hall935db192016-04-19 00:22:04 -07004331 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004332 """
4333 CLI command to get a distributed counter then add a delta to it.
4334 Required arguments:
4335 counter - The name of the counter to increment.
4336 Optional arguments:
4337 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004338 returns:
4339 integer value of the counter or
4340 None on Error
4341 """
4342 try:
4343 counter = str( counter )
4344 delta = int( delta )
4345 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004346 cmdStr += counter
4347 if delta != 1:
4348 cmdStr += " " + str( delta )
4349 output = self.sendline( cmdStr )
4350 try:
Jon Halla495f562016-05-16 18:03:26 -07004351 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004352 # TODO: Maybe make this less hardcoded
4353 # ConsistentMap Exceptions
4354 assert "org.onosproject.store.service" not in output
4355 # Node not leader
4356 assert "java.lang.IllegalStateException" not in output
4357 except AssertionError:
4358 main.log.error( "Error in processing '" + cmdStr + "' " +
4359 "command: " + str( output ) )
4360 retryTime = 30 # Conservative time, given by Madan
4361 main.log.info( "Waiting " + str( retryTime ) +
4362 "seconds before retrying." )
4363 time.sleep( retryTime ) # Due to change in mastership
4364 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004365 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004366 assert "Command not found:" not in output, output
4367 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004368 main.log.info( self.name + ": " + output )
4369 pattern = counter + " was updated to (-?\d+)"
4370 match = re.search( pattern, output )
4371 if match:
4372 return int( match.group( 1 ) )
4373 else:
4374 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4375 " match expected output." )
4376 main.log.debug( self.name + " expected: " + pattern )
4377 main.log.debug( self.name + " actual: " + repr( output ) )
4378 return None
4379 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004380 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004381 return None
4382 except TypeError:
4383 main.log.exception( self.name + ": Object not as expected" )
4384 return None
4385 except pexpect.EOF:
4386 main.log.error( self.name + ": EOF exception found" )
4387 main.log.error( self.name + ": " + self.handle.before )
4388 main.cleanup()
4389 main.exit()
4390 except Exception:
4391 main.log.exception( self.name + ": Uncaught exception!" )
4392 main.cleanup()
4393 main.exit()
4394
YPZhangfebf7302016-05-24 16:45:56 -07004395 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004396 """
4397 Description: Execute summary command in onos
4398 Returns: json object ( summary -j ), returns main.FALSE if there is
4399 no output
4400
4401 """
4402 try:
4403 cmdStr = "summary"
4404 if jsonFormat:
4405 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004406 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004407 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004408 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004409 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004410 if not handle:
4411 main.log.error( self.name + ": There is no output in " +
4412 "summary command" )
4413 return main.FALSE
4414 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004415 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004416 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004417 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004418 except TypeError:
4419 main.log.exception( self.name + ": Object not as expected" )
4420 return None
4421 except pexpect.EOF:
4422 main.log.error( self.name + ": EOF exception found" )
4423 main.log.error( self.name + ": " + self.handle.before )
4424 main.cleanup()
4425 main.exit()
4426 except Exception:
4427 main.log.exception( self.name + ": Uncaught exception!" )
4428 main.cleanup()
4429 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004430
Jon Hall935db192016-04-19 00:22:04 -07004431 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004432 """
4433 CLI command to get the value of a key in a consistent map using
4434 transactions. This a test function and can only get keys from the
4435 test map hard coded into the cli command
4436 Required arguments:
4437 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004438 returns:
4439 The string value of the key or
4440 None on Error
4441 """
4442 try:
4443 keyName = str( keyName )
4444 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004445 cmdStr += keyName
4446 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004447 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004448 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004449 try:
4450 # TODO: Maybe make this less hardcoded
4451 # ConsistentMap Exceptions
4452 assert "org.onosproject.store.service" not in output
4453 # Node not leader
4454 assert "java.lang.IllegalStateException" not in output
4455 except AssertionError:
4456 main.log.error( "Error in processing '" + cmdStr + "' " +
4457 "command: " + str( output ) )
4458 return None
4459 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4460 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004461 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004462 return None
4463 else:
4464 match = re.search( pattern, output )
4465 if match:
4466 return match.groupdict()[ 'value' ]
4467 else:
4468 main.log.error( self.name + ": transactionlMapGet did not" +
4469 " match expected output." )
4470 main.log.debug( self.name + " expected: " + pattern )
4471 main.log.debug( self.name + " actual: " + repr( output ) )
4472 return None
Jon Hallc6793552016-01-19 14:18:37 -08004473 except AssertionError:
4474 main.log.exception( "" )
4475 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004476 except TypeError:
4477 main.log.exception( self.name + ": Object not as expected" )
4478 return None
4479 except pexpect.EOF:
4480 main.log.error( self.name + ": EOF exception found" )
4481 main.log.error( self.name + ": " + self.handle.before )
4482 main.cleanup()
4483 main.exit()
4484 except Exception:
4485 main.log.exception( self.name + ": Uncaught exception!" )
4486 main.cleanup()
4487 main.exit()
4488
Jon Hall935db192016-04-19 00:22:04 -07004489 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004490 """
4491 CLI command to put a value into 'numKeys' number of keys in a
4492 consistent map using transactions. This a test function and can only
4493 put into keys named 'Key#' of the test map hard coded into the cli command
4494 Required arguments:
4495 numKeys - Number of keys to add the value to
4496 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004497 returns:
4498 A dictionary whose keys are the name of the keys put into the map
4499 and the values of the keys are dictionaries whose key-values are
4500 'value': value put into map and optionaly
4501 'oldValue': Previous value in the key or
4502 None on Error
4503
4504 Example output
4505 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4506 'Key2': {'value': 'Testing'} }
4507 """
4508 try:
4509 numKeys = str( numKeys )
4510 value = str( value )
4511 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004512 cmdStr += numKeys + " " + value
4513 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004514 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004515 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004516 try:
4517 # TODO: Maybe make this less hardcoded
4518 # ConsistentMap Exceptions
4519 assert "org.onosproject.store.service" not in output
4520 # Node not leader
4521 assert "java.lang.IllegalStateException" not in output
4522 except AssertionError:
4523 main.log.error( "Error in processing '" + cmdStr + "' " +
4524 "command: " + str( output ) )
4525 return None
4526 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4527 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4528 results = {}
4529 for line in output.splitlines():
4530 new = re.search( newPattern, line )
4531 updated = re.search( updatedPattern, line )
4532 if new:
4533 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4534 elif updated:
4535 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004536 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004537 else:
4538 main.log.error( self.name + ": transactionlMapGet did not" +
4539 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004540 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4541 newPattern,
4542 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004543 main.log.debug( self.name + " actual: " + repr( output ) )
4544 return results
Jon Hallc6793552016-01-19 14:18:37 -08004545 except AssertionError:
4546 main.log.exception( "" )
4547 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004548 except TypeError:
4549 main.log.exception( self.name + ": Object not as expected" )
4550 return None
4551 except pexpect.EOF:
4552 main.log.error( self.name + ": EOF exception found" )
4553 main.log.error( self.name + ": " + self.handle.before )
4554 main.cleanup()
4555 main.exit()
4556 except Exception:
4557 main.log.exception( self.name + ": Uncaught exception!" )
4558 main.cleanup()
4559 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004560
acsmarsdaea66c2015-09-03 11:44:06 -07004561 def maps( self, jsonFormat=True ):
4562 """
4563 Description: Returns result of onos:maps
4564 Optional:
4565 * jsonFormat: enable json formatting of output
4566 """
4567 try:
4568 cmdStr = "maps"
4569 if jsonFormat:
4570 cmdStr += " -j"
4571 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004572 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004573 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004574 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004575 except AssertionError:
4576 main.log.exception( "" )
4577 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004578 except TypeError:
4579 main.log.exception( self.name + ": Object not as expected" )
4580 return None
4581 except pexpect.EOF:
4582 main.log.error( self.name + ": EOF exception found" )
4583 main.log.error( self.name + ": " + self.handle.before )
4584 main.cleanup()
4585 main.exit()
4586 except Exception:
4587 main.log.exception( self.name + ": Uncaught exception!" )
4588 main.cleanup()
4589 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004590
4591 def getSwController( self, uri, jsonFormat=True ):
4592 """
4593 Descrition: Gets the controller information from the device
4594 """
4595 try:
4596 cmd = "device-controllers "
4597 if jsonFormat:
4598 cmd += "-j "
4599 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004600 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004601 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004602 return response
Jon Hallc6793552016-01-19 14:18:37 -08004603 except AssertionError:
4604 main.log.exception( "" )
4605 return None
GlennRC050596c2015-11-18 17:06:41 -08004606 except TypeError:
4607 main.log.exception( self.name + ": Object not as expected" )
4608 return None
4609 except pexpect.EOF:
4610 main.log.error( self.name + ": EOF exception found" )
4611 main.log.error( self.name + ": " + self.handle.before )
4612 main.cleanup()
4613 main.exit()
4614 except Exception:
4615 main.log.exception( self.name + ": Uncaught exception!" )
4616 main.cleanup()
4617 main.exit()
4618
4619 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4620 """
4621 Descrition: sets the controller(s) for the specified device
4622
4623 Parameters:
4624 Required: uri - String: The uri of the device(switch).
4625 ip - String or List: The ip address of the controller.
4626 This parameter can be formed in a couple of different ways.
4627 VALID:
4628 10.0.0.1 - just the ip address
4629 tcp:10.0.0.1 - the protocol and the ip address
4630 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4631 so that you can add controllers with different
4632 protocols and ports
4633 INVALID:
4634 10.0.0.1:6653 - this is not supported by ONOS
4635
4636 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4637 port - The port number.
4638 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4639
4640 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4641 """
4642 try:
4643 cmd = "device-setcontrollers"
4644
4645 if jsonFormat:
4646 cmd += " -j"
4647 cmd += " " + uri
4648 if isinstance( ip, str ):
4649 ip = [ip]
4650 for item in ip:
4651 if ":" in item:
4652 sitem = item.split( ":" )
4653 if len(sitem) == 3:
4654 cmd += " " + item
4655 elif "." in sitem[1]:
4656 cmd += " {}:{}".format(item, port)
4657 else:
4658 main.log.error( "Malformed entry: " + item )
4659 raise TypeError
4660 else:
4661 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004662 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004663 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004664 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004665 if "Error" in response:
4666 main.log.error( response )
4667 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004668 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004669 except AssertionError:
4670 main.log.exception( "" )
4671 return None
GlennRC050596c2015-11-18 17:06:41 -08004672 except TypeError:
4673 main.log.exception( self.name + ": Object not as expected" )
4674 return main.FALSE
4675 except pexpect.EOF:
4676 main.log.error( self.name + ": EOF exception found" )
4677 main.log.error( self.name + ": " + self.handle.before )
4678 main.cleanup()
4679 main.exit()
4680 except Exception:
4681 main.log.exception( self.name + ": Uncaught exception!" )
4682 main.cleanup()
4683 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004684
4685 def removeDevice( self, device ):
4686 '''
4687 Description:
4688 Remove a device from ONOS by passing the uri of the device(s).
4689 Parameters:
4690 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4691 Returns:
4692 Returns main.FALSE if an exception is thrown or an error is present
4693 in the response. Otherwise, returns main.TRUE.
4694 NOTE:
4695 If a host cannot be removed, then this function will return main.FALSE
4696 '''
4697 try:
4698 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004699 deviceStr = device
4700 device = []
4701 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004702
4703 for d in device:
4704 time.sleep( 1 )
4705 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004706 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004707 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004708 if "Error" in response:
4709 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4710 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004711 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004712 except AssertionError:
4713 main.log.exception( "" )
4714 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004715 except TypeError:
4716 main.log.exception( self.name + ": Object not as expected" )
4717 return main.FALSE
4718 except pexpect.EOF:
4719 main.log.error( self.name + ": EOF exception found" )
4720 main.log.error( self.name + ": " + self.handle.before )
4721 main.cleanup()
4722 main.exit()
4723 except Exception:
4724 main.log.exception( self.name + ": Uncaught exception!" )
4725 main.cleanup()
4726 main.exit()
4727
4728 def removeHost( self, host ):
4729 '''
4730 Description:
4731 Remove a host from ONOS by passing the id of the host(s)
4732 Parameters:
4733 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4734 Returns:
4735 Returns main.FALSE if an exception is thrown or an error is present
4736 in the response. Otherwise, returns main.TRUE.
4737 NOTE:
4738 If a host cannot be removed, then this function will return main.FALSE
4739 '''
4740 try:
4741 if type( host ) is str:
4742 host = list( host )
4743
4744 for h in host:
4745 time.sleep( 1 )
4746 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004747 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004748 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004749 if "Error" in response:
4750 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4751 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004752 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004753 except AssertionError:
4754 main.log.exception( "" )
4755 return None
GlennRC20fc6522015-12-23 23:26:57 -08004756 except TypeError:
4757 main.log.exception( self.name + ": Object not as expected" )
4758 return main.FALSE
4759 except pexpect.EOF:
4760 main.log.error( self.name + ": EOF exception found" )
4761 main.log.error( self.name + ": " + self.handle.before )
4762 main.cleanup()
4763 main.exit()
4764 except Exception:
4765 main.log.exception( self.name + ": Uncaught exception!" )
4766 main.cleanup()
4767 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004768
YPZhangfebf7302016-05-24 16:45:56 -07004769 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004770 '''
4771 Description:
4772 Bring link down or up in the null-provider.
4773 params:
4774 begin - (string) One end of a device or switch.
4775 end - (string) the other end of the device or switch
4776 returns:
4777 main.TRUE if no exceptions were thrown and no Errors are
4778 present in the resoponse. Otherwise, returns main.FALSE
4779 '''
4780 try:
Jon Hallc6793552016-01-19 14:18:37 -08004781 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004782 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004783 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004784 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004785 if "Error" in response or "Failure" in response:
4786 main.log.error( response )
4787 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004788 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004789 except AssertionError:
4790 main.log.exception( "" )
4791 return None
GlennRCed771242016-01-13 17:02:47 -08004792 except TypeError:
4793 main.log.exception( self.name + ": Object not as expected" )
4794 return main.FALSE
4795 except pexpect.EOF:
4796 main.log.error( self.name + ": EOF exception found" )
4797 main.log.error( self.name + ": " + self.handle.before )
4798 main.cleanup()
4799 main.exit()
4800 except Exception:
4801 main.log.exception( self.name + ": Uncaught exception!" )
4802 main.cleanup()
4803 main.exit()
4804
Flavio Castro82ee2f62016-06-07 15:04:12 -07004805 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4806 '''
4807 Description:
4808 Changes the state of port in an OF switch by means of the
4809 PORTSTATUS OF messages.
4810 params:
4811 dpid - (string) Datapath ID of the device
4812 port - (string) target port in the device
4813 state - (string) target state (enable or disabled)
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:
4819 cmd = "portstate {} {} {}".format( dpid, port, state )
4820 response = self.sendline( cmd, showResponse=True )
4821 assert response is not None, "Error in sendline"
4822 assert "Command not found:" not in response, response
4823 if "Error" in response or "Failure" in response:
4824 main.log.error( response )
4825 return main.FALSE
4826 return main.TRUE
4827 except AssertionError:
4828 main.log.exception( "" )
4829 return None
4830 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
4843 def logSet( self, level="INFO", app="org.onosproject" ):
4844 """
4845 Set the logging level to lvl for a specific app
4846 returns main.TRUE on success
4847 returns main.FALSE if Error occurred
4848 if noExit is True, TestON will not exit, but clean up
4849 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4850 Level defaults to INFO
4851 """
4852 try:
4853 self.handle.sendline( "log:set %s %s" %( level, app ) )
4854 self.handle.expect( "onos>" )
4855
4856 response = self.handle.before
4857 if re.search( "Error", response ):
4858 return main.FALSE
4859 return main.TRUE
4860 except pexpect.TIMEOUT:
4861 main.log.exception( self.name + ": TIMEOUT exception found" )
4862 main.cleanup()
4863 main.exit()
4864 except pexpect.EOF:
4865 main.log.error( self.name + ": EOF exception found" )
4866 main.log.error( self.name + ": " + self.handle.before )
4867 main.cleanup()
4868 main.exit()
4869 except Exception:
4870 main.log.exception( self.name + ": Uncaught exception!" )
4871 main.cleanup()
4872 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004873
4874 def getGraphDict( self, timeout=60, includeHost=False ):
4875 """
4876 Return a dictionary which describes the latest network topology data as a
4877 graph.
4878 An example of the dictionary:
4879 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4880 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4881 Each vertex should at least have an 'edges' attribute which describes the
4882 adjacency information. The value of 'edges' attribute is also represented by
4883 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4884 list of attributes.
4885 An example of the edges dictionary:
4886 'edges': { vertex2: { 'port': ..., 'weight': ... },
4887 vertex3: { 'port': ..., 'weight': ... } }
4888 If includeHost == True, all hosts (and host-switch links) will be included
4889 in topology data.
4890 """
4891 graphDict = {}
4892 try:
4893 links = self.links()
4894 links = json.loads( links )
4895 devices = self.devices()
4896 devices = json.loads( devices )
4897 idToDevice = {}
4898 for device in devices:
4899 idToDevice[ device[ 'id' ] ] = device
4900 if includeHost:
4901 hosts = self.hosts()
4902 # FIXME: support 'includeHost' argument
4903 for link in links:
4904 nodeA = link[ 'src' ][ 'device' ]
4905 nodeB = link[ 'dst' ][ 'device' ]
4906 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4907 if not nodeA in graphDict.keys():
4908 graphDict[ nodeA ] = { 'edges':{},
4909 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4910 'type':idToDevice[ nodeA ][ 'type' ],
4911 'available':idToDevice[ nodeA ][ 'available' ],
4912 'role':idToDevice[ nodeA ][ 'role' ],
4913 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4914 'hw':idToDevice[ nodeA ][ 'hw' ],
4915 'sw':idToDevice[ nodeA ][ 'sw' ],
4916 'serial':idToDevice[ nodeA ][ 'serial' ],
4917 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4918 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4919 else:
4920 # Assert nodeB is not connected to any current links of nodeA
4921 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4922 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4923 'type':link[ 'type' ],
4924 'state':link[ 'state' ] }
4925 return graphDict
4926 except ( TypeError, ValueError ):
4927 main.log.exception( self.name + ": Object not as expected" )
4928 return None
4929 except KeyError:
4930 main.log.exception( self.name + ": KeyError exception found" )
4931 return None
4932 except AssertionError:
4933 main.log.exception( self.name + ": AssertionError exception found" )
4934 return None
4935 except pexpect.EOF:
4936 main.log.error( self.name + ": EOF exception found" )
4937 main.log.error( self.name + ": " + self.handle.before )
4938 return None
4939 except Exception:
4940 main.log.exception( self.name + ": Uncaught exception!" )
4941 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004942
4943 def getIntentPerfSummary( self ):
4944 '''
4945 Send command to check intent-perf summary
4946 Returns: dictionary for intent-perf summary
4947 if something wrong, function will return None
4948 '''
4949 cmd = "intent-perf -s"
4950 respDic = {}
4951 resp = self.sendline( cmd )
4952 try:
4953 # Generate the dictionary to return
4954 for l in resp.split( "\n" ):
4955 # Delete any white space in line
4956 temp = re.sub( r'\s+', '', l )
4957 temp = temp.split( ":" )
4958 respDic[ temp[0] ] = temp[ 1 ]
4959
4960 except (TypeError, ValueError):
4961 main.log.exception( self.name + ": Object not as expected" )
4962 return None
4963 except KeyError:
4964 main.log.exception( self.name + ": KeyError exception found" )
4965 return None
4966 except AssertionError:
4967 main.log.exception( self.name + ": AssertionError exception found" )
4968 return None
4969 except pexpect.EOF:
4970 main.log.error( self.name + ": EOF exception found" )
4971 main.log.error( self.name + ": " + self.handle.before )
4972 return None
4973 except Exception:
4974 main.log.exception( self.name + ": Uncaught exception!" )
4975 return None
4976 return respDic
4977
4978