blob: ebfd8a5a58f9ea54ba21af7217842c9374956c10 [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 Songsterc032f162016-08-04 17:14:49 -07001159 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
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
Jeremy Songsterc032f162016-08-04 17:14:49 -07001167 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001168 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001169 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001170 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001171 Returns:
1172 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001173 """
andrewonlabe6745342014-10-17 14:29:13 -04001174 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001175 cmdStr = "add-host-intent "
1176 if vlanId:
1177 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001178 if setVlan:
1179 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001180 if encap:
1181 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001182 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001183 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001184 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001185 if re.search( "Error", handle ):
1186 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001187 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001189 else:
1190 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001191 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1192 match = re.search('id=0x([\da-f]+),', handle)
1193 if match:
1194 return match.group()[3:-1]
1195 else:
1196 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001197 main.log.debug( "Response from ONOS was: " +
1198 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001199 return None
Jon Hallc6793552016-01-19 14:18:37 -08001200 except AssertionError:
1201 main.log.exception( "" )
1202 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001203 except TypeError:
1204 main.log.exception( self.name + ": Object not as expected" )
1205 return None
andrewonlabe6745342014-10-17 14:29:13 -04001206 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001207 main.log.error( self.name + ": EOF exception found" )
1208 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001209 main.cleanup()
1210 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001211 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001212 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001213 main.cleanup()
1214 main.exit()
1215
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001217 """
andrewonlab7b31d232014-10-24 13:31:47 -04001218 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 * ingressDevice: device id of ingress device
1220 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001221 Optional:
1222 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001223 Description:
1224 Adds an optical intent by specifying an ingress and egress device
1225 Returns:
1226 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001227 """
andrewonlab7b31d232014-10-24 13:31:47 -04001228 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1230 " " + str( egressDevice )
1231 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001232 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001233 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001234 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 main.log.error( "Error in adding Optical intent" )
1236 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001237 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 main.log.info( "Optical intent installed between " +
1239 str( ingressDevice ) + " and " +
1240 str( egressDevice ) )
1241 match = re.search('id=0x([\da-f]+),', handle)
1242 if match:
1243 return match.group()[3:-1]
1244 else:
1245 main.log.error( "Error, intent ID not found" )
1246 return None
Jon Hallc6793552016-01-19 14:18:37 -08001247 except AssertionError:
1248 main.log.exception( "" )
1249 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001250 except TypeError:
1251 main.log.exception( self.name + ": Object not as expected" )
1252 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001256 main.cleanup()
1257 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001258 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001259 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001260 main.cleanup()
1261 main.exit()
1262
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 ingressDevice,
1266 egressDevice,
1267 portIngress="",
1268 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 ethType="",
1270 ethSrc="",
1271 ethDst="",
1272 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 ipProto="",
1275 ipSrc="",
1276 ipDst="",
1277 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001278 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001279 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001280 setVlan="",
1281 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001282 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001283 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001284 * ingressDevice: device id of ingress device
1285 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001286 Optional:
1287 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001288 * ethSrc: specify ethSrc ( i.e. src mac addr )
1289 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001290 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001292 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001293 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001294 * ipSrc: specify ip source address
1295 * ipDst: specify ip destination address
1296 * tcpSrc: specify tcp source port
1297 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001298 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001299 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001300 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001301 Description:
kelvin8ec71442015-01-15 16:57:00 -08001302 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001303 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001304 Returns:
1305 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001306
Jon Halle3f39ff2015-01-13 11:50:53 -08001307 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001308 options developers provide for point-to-point
1309 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001310 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001311 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001312 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001313
Jeremy Songsterff553672016-05-12 17:06:23 -07001314 if ethType:
1315 cmd += " --ethType " + str( ethType )
1316 if ethSrc:
1317 cmd += " --ethSrc " + str( ethSrc )
1318 if ethDst:
1319 cmd += " --ethDst " + str( ethDst )
1320 if bandwidth:
1321 cmd += " --bandwidth " + str( bandwidth )
1322 if lambdaAlloc:
1323 cmd += " --lambda "
1324 if ipProto:
1325 cmd += " --ipProto " + str( ipProto )
1326 if ipSrc:
1327 cmd += " --ipSrc " + str( ipSrc )
1328 if ipDst:
1329 cmd += " --ipDst " + str( ipDst )
1330 if tcpSrc:
1331 cmd += " --tcpSrc " + str( tcpSrc )
1332 if tcpDst:
1333 cmd += " --tcpDst " + str( tcpDst )
1334 if vlanId:
1335 cmd += " -v " + str( vlanId )
1336 if setVlan:
1337 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001338 if encap:
1339 cmd += " --encapsulation " + str( encap )
andrewonlab289e4b72014-10-21 21:24:18 -04001340
kelvin8ec71442015-01-15 16:57:00 -08001341 # Check whether the user appended the port
1342 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 if "/" in ingressDevice:
1344 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001345 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001347 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001348 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 # Would it make sense to throw an exception and exit
1350 # the test?
1351 return None
andrewonlab36af3822014-11-18 17:48:18 -05001352
kelvin8ec71442015-01-15 16:57:00 -08001353 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 str( ingressDevice ) + "/" +\
1355 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001356
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if "/" in egressDevice:
1358 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001359 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001361 main.log.error( "You must specify the egress port" )
1362 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001363
kelvin8ec71442015-01-15 16:57:00 -08001364 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 str( egressDevice ) + "/" +\
1366 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001367
kelvin-onlab898a6c62015-01-16 14:13:53 -08001368 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001369 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001371 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001372 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001373 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001374 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001375 # TODO: print out all the options in this message?
1376 main.log.info( "Point-to-point intent installed between " +
1377 str( ingressDevice ) + " and " +
1378 str( egressDevice ) )
1379 match = re.search('id=0x([\da-f]+),', handle)
1380 if match:
1381 return match.group()[3:-1]
1382 else:
1383 main.log.error( "Error, intent ID not found" )
1384 return None
Jon Hallc6793552016-01-19 14:18:37 -08001385 except AssertionError:
1386 main.log.exception( "" )
1387 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001388 except TypeError:
1389 main.log.exception( self.name + ": Object not as expected" )
1390 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001391 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001392 main.log.error( self.name + ": EOF exception found" )
1393 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001394 main.cleanup()
1395 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001396 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001397 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001398 main.cleanup()
1399 main.exit()
1400
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001402 self,
shahshreyac2f97072015-03-19 17:04:29 -07001403 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001405 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001407 ethType="",
1408 ethSrc="",
1409 ethDst="",
1410 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001412 ipProto="",
1413 ipSrc="",
1414 ipDst="",
1415 tcpSrc="",
1416 tcpDst="",
1417 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001418 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001419 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001420 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001421 partial=False,
1422 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001423 """
shahshreyad0c80432014-12-04 16:56:05 -08001424 Note:
shahshreya70622b12015-03-19 17:19:00 -07001425 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001426 is same. That is, all ingress devices include port numbers
1427 with a "/" or all ingress devices could specify device
1428 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001429 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001430 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001431 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001432 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001433 Optional:
1434 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001435 * ethSrc: specify ethSrc ( i.e. src mac addr )
1436 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001437 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001438 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001439 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001440 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001441 * ipSrc: specify ip source address
1442 * ipDst: specify ip destination address
1443 * tcpSrc: specify tcp source port
1444 * tcpDst: specify tcp destination port
1445 * setEthSrc: action to Rewrite Source MAC Address
1446 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001447 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001448 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001449 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001450 Description:
kelvin8ec71442015-01-15 16:57:00 -08001451 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001452 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001453 Returns:
1454 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001455
Jon Halle3f39ff2015-01-13 11:50:53 -08001456 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001457 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001458 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001459 """
shahshreyad0c80432014-12-04 16:56:05 -08001460 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001461 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001462
Jeremy Songsterff553672016-05-12 17:06:23 -07001463 if ethType:
1464 cmd += " --ethType " + str( ethType )
1465 if ethSrc:
1466 cmd += " --ethSrc " + str( ethSrc )
1467 if ethDst:
1468 cmd += " --ethDst " + str( ethDst )
1469 if bandwidth:
1470 cmd += " --bandwidth " + str( bandwidth )
1471 if lambdaAlloc:
1472 cmd += " --lambda "
1473 if ipProto:
1474 cmd += " --ipProto " + str( ipProto )
1475 if ipSrc:
1476 cmd += " --ipSrc " + str( ipSrc )
1477 if ipDst:
1478 cmd += " --ipDst " + str( ipDst )
1479 if tcpSrc:
1480 cmd += " --tcpSrc " + str( tcpSrc )
1481 if tcpDst:
1482 cmd += " --tcpDst " + str( tcpDst )
1483 if setEthSrc:
1484 cmd += " --setEthSrc " + str( setEthSrc )
1485 if setEthDst:
1486 cmd += " --setEthDst " + str( setEthDst )
1487 if vlanId:
1488 cmd += " -v " + str( vlanId )
1489 if setVlan:
1490 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001491 if partial:
1492 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001493 if encap:
1494 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001495
kelvin8ec71442015-01-15 16:57:00 -08001496 # Check whether the user appended the port
1497 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001498
1499 if portIngressList is None:
1500 for ingressDevice in ingressDeviceList:
1501 if "/" in ingressDevice:
1502 cmd += " " + str( ingressDevice )
1503 else:
1504 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001505 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001506 # TODO: perhaps more meaningful return
1507 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001508 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001509 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001510 for ingressDevice, portIngress in zip( ingressDeviceList,
1511 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001512 cmd += " " + \
1513 str( ingressDevice ) + "/" +\
1514 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001515 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001516 main.log.error( "Device list and port list does not " +
1517 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001518 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 if "/" in egressDevice:
1520 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001521 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001523 main.log.error( "You must specify " +
1524 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001525 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001526
kelvin8ec71442015-01-15 16:57:00 -08001527 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001528 str( egressDevice ) + "/" +\
1529 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001530 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001531 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001532 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001533 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001534 main.log.error( "Error in adding multipoint-to-singlepoint " +
1535 "intent" )
1536 return None
shahshreyad0c80432014-12-04 16:56:05 -08001537 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001538 match = re.search('id=0x([\da-f]+),', handle)
1539 if match:
1540 return match.group()[3:-1]
1541 else:
1542 main.log.error( "Error, intent ID not found" )
1543 return None
Jon Hallc6793552016-01-19 14:18:37 -08001544 except AssertionError:
1545 main.log.exception( "" )
1546 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001547 except TypeError:
1548 main.log.exception( self.name + ": Object not as expected" )
1549 return None
1550 except pexpect.EOF:
1551 main.log.error( self.name + ": EOF exception found" )
1552 main.log.error( self.name + ": " + self.handle.before )
1553 main.cleanup()
1554 main.exit()
1555 except Exception:
1556 main.log.exception( self.name + ": Uncaught exception!" )
1557 main.cleanup()
1558 main.exit()
1559
1560 def addSinglepointToMultipointIntent(
1561 self,
1562 ingressDevice,
1563 egressDeviceList,
1564 portIngress="",
1565 portEgressList=None,
1566 ethType="",
1567 ethSrc="",
1568 ethDst="",
1569 bandwidth="",
1570 lambdaAlloc=False,
1571 ipProto="",
1572 ipSrc="",
1573 ipDst="",
1574 tcpSrc="",
1575 tcpDst="",
1576 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001577 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001578 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001579 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001580 partial=False,
1581 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001582 """
1583 Note:
1584 This function assumes the format of all egress devices
1585 is same. That is, all egress devices include port numbers
1586 with a "/" or all egress devices could specify device
1587 ids and port numbers seperately.
1588 Required:
1589 * EgressDeviceList: List of device ids of egress device
1590 ( Atleast 2 eress devices required in the list )
1591 * ingressDevice: device id of ingress device
1592 Optional:
1593 * ethType: specify ethType
1594 * ethSrc: specify ethSrc ( i.e. src mac addr )
1595 * ethDst: specify ethDst ( i.e. dst mac addr )
1596 * bandwidth: specify bandwidth capacity of link
1597 * lambdaAlloc: if True, intent will allocate lambda
1598 for the specified intent
1599 * ipProto: specify ip protocol
1600 * ipSrc: specify ip source address
1601 * ipDst: specify ip destination address
1602 * tcpSrc: specify tcp source port
1603 * tcpDst: specify tcp destination port
1604 * setEthSrc: action to Rewrite Source MAC Address
1605 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001606 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001607 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001608 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001609 Description:
1610 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1611 specifying device id's and optional fields
1612 Returns:
1613 A string of the intent id or None on error
1614
1615 NOTE: This function may change depending on the
1616 options developers provide for singlepoint-to-multipoint
1617 intent via cli
1618 """
1619 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001620 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001621
Jeremy Songsterff553672016-05-12 17:06:23 -07001622 if ethType:
1623 cmd += " --ethType " + str( ethType )
1624 if ethSrc:
1625 cmd += " --ethSrc " + str( ethSrc )
1626 if ethDst:
1627 cmd += " --ethDst " + str( ethDst )
1628 if bandwidth:
1629 cmd += " --bandwidth " + str( bandwidth )
1630 if lambdaAlloc:
1631 cmd += " --lambda "
1632 if ipProto:
1633 cmd += " --ipProto " + str( ipProto )
1634 if ipSrc:
1635 cmd += " --ipSrc " + str( ipSrc )
1636 if ipDst:
1637 cmd += " --ipDst " + str( ipDst )
1638 if tcpSrc:
1639 cmd += " --tcpSrc " + str( tcpSrc )
1640 if tcpDst:
1641 cmd += " --tcpDst " + str( tcpDst )
1642 if setEthSrc:
1643 cmd += " --setEthSrc " + str( setEthSrc )
1644 if setEthDst:
1645 cmd += " --setEthDst " + str( setEthDst )
1646 if vlanId:
1647 cmd += " -v " + str( vlanId )
1648 if setVlan:
1649 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001650 if partial:
1651 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001652 if encap:
1653 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001654
1655 # Check whether the user appended the port
1656 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001657
kelvin-onlabb9408212015-04-01 13:34:04 -07001658 if "/" in ingressDevice:
1659 cmd += " " + str( ingressDevice )
1660 else:
1661 if not portIngress:
1662 main.log.error( "You must specify " +
1663 "the Ingress port" )
1664 return main.FALSE
1665
1666 cmd += " " +\
1667 str( ingressDevice ) + "/" +\
1668 str( portIngress )
1669
1670 if portEgressList is None:
1671 for egressDevice in egressDeviceList:
1672 if "/" in egressDevice:
1673 cmd += " " + str( egressDevice )
1674 else:
1675 main.log.error( "You must specify " +
1676 "the egress port" )
1677 # TODO: perhaps more meaningful return
1678 return main.FALSE
1679 else:
1680 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001681 for egressDevice, portEgress in zip( egressDeviceList,
1682 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001683 cmd += " " + \
1684 str( egressDevice ) + "/" +\
1685 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001686 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001687 main.log.error( "Device list and port list does not " +
1688 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001689 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001690 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001691 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001692 # If error, return error message
1693 if re.search( "Error", handle ):
1694 main.log.error( "Error in adding singlepoint-to-multipoint " +
1695 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001696 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001697 else:
1698 match = re.search('id=0x([\da-f]+),', handle)
1699 if match:
1700 return match.group()[3:-1]
1701 else:
1702 main.log.error( "Error, intent ID not found" )
1703 return None
Jon Hallc6793552016-01-19 14:18:37 -08001704 except AssertionError:
1705 main.log.exception( "" )
1706 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001707 except TypeError:
1708 main.log.exception( self.name + ": Object not as expected" )
1709 return None
shahshreyad0c80432014-12-04 16:56:05 -08001710 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001711 main.log.error( self.name + ": EOF exception found" )
1712 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001713 main.cleanup()
1714 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001715 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001716 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001717 main.cleanup()
1718 main.exit()
1719
Hari Krishna9e232602015-04-13 17:29:08 -07001720 def addMplsIntent(
1721 self,
1722 ingressDevice,
1723 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001724 ingressPort="",
1725 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001726 ethType="",
1727 ethSrc="",
1728 ethDst="",
1729 bandwidth="",
1730 lambdaAlloc=False,
1731 ipProto="",
1732 ipSrc="",
1733 ipDst="",
1734 tcpSrc="",
1735 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001736 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001737 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001738 priority=""):
1739 """
1740 Required:
1741 * ingressDevice: device id of ingress device
1742 * egressDevice: device id of egress device
1743 Optional:
1744 * ethType: specify ethType
1745 * ethSrc: specify ethSrc ( i.e. src mac addr )
1746 * ethDst: specify ethDst ( i.e. dst mac addr )
1747 * bandwidth: specify bandwidth capacity of link
1748 * lambdaAlloc: if True, intent will allocate lambda
1749 for the specified intent
1750 * ipProto: specify ip protocol
1751 * ipSrc: specify ip source address
1752 * ipDst: specify ip destination address
1753 * tcpSrc: specify tcp source port
1754 * tcpDst: specify tcp destination port
1755 * ingressLabel: Ingress MPLS label
1756 * egressLabel: Egress MPLS label
1757 Description:
1758 Adds MPLS intent by
1759 specifying device id's and optional fields
1760 Returns:
1761 A string of the intent id or None on error
1762
1763 NOTE: This function may change depending on the
1764 options developers provide for MPLS
1765 intent via cli
1766 """
1767 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001768 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001769
Jeremy Songsterff553672016-05-12 17:06:23 -07001770 if ethType:
1771 cmd += " --ethType " + str( ethType )
1772 if ethSrc:
1773 cmd += " --ethSrc " + str( ethSrc )
1774 if ethDst:
1775 cmd += " --ethDst " + str( ethDst )
1776 if bandwidth:
1777 cmd += " --bandwidth " + str( bandwidth )
1778 if lambdaAlloc:
1779 cmd += " --lambda "
1780 if ipProto:
1781 cmd += " --ipProto " + str( ipProto )
1782 if ipSrc:
1783 cmd += " --ipSrc " + str( ipSrc )
1784 if ipDst:
1785 cmd += " --ipDst " + str( ipDst )
1786 if tcpSrc:
1787 cmd += " --tcpSrc " + str( tcpSrc )
1788 if tcpDst:
1789 cmd += " --tcpDst " + str( tcpDst )
1790 if ingressLabel:
1791 cmd += " --ingressLabel " + str( ingressLabel )
1792 if egressLabel:
1793 cmd += " --egressLabel " + str( egressLabel )
1794 if priority:
1795 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001796
1797 # Check whether the user appended the port
1798 # or provided it as an input
1799 if "/" in ingressDevice:
1800 cmd += " " + str( ingressDevice )
1801 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001802 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001803 main.log.error( "You must specify the ingress port" )
1804 return None
1805
1806 cmd += " " + \
1807 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001808 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001809
1810 if "/" in egressDevice:
1811 cmd += " " + str( egressDevice )
1812 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001813 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001814 main.log.error( "You must specify the egress port" )
1815 return None
1816
1817 cmd += " " +\
1818 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001819 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001820
1821 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001822 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001823 # If error, return error message
1824 if re.search( "Error", handle ):
1825 main.log.error( "Error in adding mpls intent" )
1826 return None
1827 else:
1828 # TODO: print out all the options in this message?
1829 main.log.info( "MPLS intent installed between " +
1830 str( ingressDevice ) + " and " +
1831 str( egressDevice ) )
1832 match = re.search('id=0x([\da-f]+),', handle)
1833 if match:
1834 return match.group()[3:-1]
1835 else:
1836 main.log.error( "Error, intent ID not found" )
1837 return None
Jon Hallc6793552016-01-19 14:18:37 -08001838 except AssertionError:
1839 main.log.exception( "" )
1840 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001841 except TypeError:
1842 main.log.exception( self.name + ": Object not as expected" )
1843 return None
1844 except pexpect.EOF:
1845 main.log.error( self.name + ": EOF exception found" )
1846 main.log.error( self.name + ": " + self.handle.before )
1847 main.cleanup()
1848 main.exit()
1849 except Exception:
1850 main.log.exception( self.name + ": Uncaught exception!" )
1851 main.cleanup()
1852 main.exit()
1853
Jon Hallefbd9792015-03-05 16:11:36 -08001854 def removeIntent( self, intentId, app='org.onosproject.cli',
1855 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001856 """
shahshreya1c818fc2015-02-26 13:44:08 -08001857 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001858 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001859 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001860 -p or --purge: Purge the intent from the store after removal
1861
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001863 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001865 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001866 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001867 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001868 if purge:
1869 cmdStr += " -p"
1870 if sync:
1871 cmdStr += " -s"
1872
1873 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001874 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001875 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001876 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001877 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001878 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001880 # TODO: Should this be main.TRUE
1881 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001882 except AssertionError:
1883 main.log.exception( "" )
1884 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001885 except TypeError:
1886 main.log.exception( self.name + ": Object not as expected" )
1887 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001888 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001889 main.log.error( self.name + ": EOF exception found" )
1890 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001891 main.cleanup()
1892 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001894 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001895 main.cleanup()
1896 main.exit()
1897
YPZhangfebf7302016-05-24 16:45:56 -07001898 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001899 """
1900 Description:
1901 Remove all the intents
1902 Optional args:-
1903 -s or --sync: Waits for the removal before returning
1904 -p or --purge: Purge the intent from the store after removal
1905 Returns:
1906 Returns main.TRUE if all intents are removed, otherwise returns
1907 main.FALSE; Returns None for exception
1908 """
1909 try:
1910 cmdStr = "remove-intent"
1911 if purge:
1912 cmdStr += " -p"
1913 if sync:
1914 cmdStr += " -s"
1915
1916 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001917 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001918 assert "Command not found:" not in handle, handle
1919 if re.search( "Error", handle ):
1920 main.log.error( "Error in removing intent" )
1921 return main.FALSE
1922 else:
1923 return main.TRUE
1924 except AssertionError:
1925 main.log.exception( "" )
1926 return None
1927 except TypeError:
1928 main.log.exception( self.name + ": Object not as expected" )
1929 return None
1930 except pexpect.EOF:
1931 main.log.error( self.name + ": EOF exception found" )
1932 main.log.error( self.name + ": " + self.handle.before )
1933 main.cleanup()
1934 main.exit()
1935 except Exception:
1936 main.log.exception( self.name + ": Uncaught exception!" )
1937 main.cleanup()
1938 main.exit()
1939
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001940 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001941 """
1942 Purges all WITHDRAWN Intents
1943 """
1944 try:
1945 cmdStr = "purge-intents"
1946 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001947 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001948 if re.search( "Error", handle ):
1949 main.log.error( "Error in purging intents" )
1950 return main.FALSE
1951 else:
1952 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001953 except AssertionError:
1954 main.log.exception( "" )
1955 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001956 except TypeError:
1957 main.log.exception( self.name + ": Object not as expected" )
1958 return None
1959 except pexpect.EOF:
1960 main.log.error( self.name + ": EOF exception found" )
1961 main.log.error( self.name + ": " + self.handle.before )
1962 main.cleanup()
1963 main.exit()
1964 except Exception:
1965 main.log.exception( self.name + ": Uncaught exception!" )
1966 main.cleanup()
1967 main.exit()
1968
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001970 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001971 NOTE: This method should be used after installing application:
1972 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001973 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001974 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 Description:
1976 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001977 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001979 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001980 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001981 cmdStr += " -j"
1982 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001983 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001984 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001985 except AssertionError:
1986 main.log.exception( "" )
1987 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001988 except TypeError:
1989 main.log.exception( self.name + ": Object not as expected" )
1990 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001991 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001994 main.cleanup()
1995 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001996 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001997 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001998 main.cleanup()
1999 main.exit()
2000
pingping-lin54b03372015-08-13 14:43:10 -07002001 def ipv4RouteNumber( self ):
2002 """
2003 NOTE: This method should be used after installing application:
2004 onos-app-sdnip
2005 Description:
2006 Obtain the total IPv4 routes number in the system
2007 """
2008 try:
2009 cmdStr = "routes -s -j"
2010 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002011 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002012 jsonResult = json.loads( handle )
2013 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002014 except AssertionError:
2015 main.log.exception( "" )
2016 return None
2017 except ( TypeError, ValueError ):
2018 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002019 return None
2020 except pexpect.EOF:
2021 main.log.error( self.name + ": EOF exception found" )
2022 main.log.error( self.name + ": " + self.handle.before )
2023 main.cleanup()
2024 main.exit()
2025 except Exception:
2026 main.log.exception( self.name + ": Uncaught exception!" )
2027 main.cleanup()
2028 main.exit()
2029
pingping-lin8244a3b2015-09-16 13:36:56 -07002030 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002031 """
andrewonlabe6745342014-10-17 14:29:13 -04002032 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002033 Obtain intents from the ONOS cli.
2034 Optional:
2035 * jsonFormat: Enable output formatting in json, default to True
2036 * summary: Whether only output the intent summary, defaults to False
2037 * type: Only output a certain type of intent. This options is valid
2038 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002039 """
andrewonlabe6745342014-10-17 14:29:13 -04002040 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002041 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002042 if summary:
2043 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002045 cmdStr += " -j"
2046 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002047 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002048 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002049 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002050 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002051 else:
Jon Hallff566d52016-01-15 14:45:36 -08002052 intentType = ""
2053 # IF we want the summary of a specific intent type
2054 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002055 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002056 if intentType in jsonResult.keys():
2057 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002058 else:
Jon Hallff566d52016-01-15 14:45:36 -08002059 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002060 return handle
2061 else:
2062 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002063 except AssertionError:
2064 main.log.exception( "" )
2065 return None
2066 except ( TypeError, ValueError ):
2067 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002068 return None
2069 except pexpect.EOF:
2070 main.log.error( self.name + ": EOF exception found" )
2071 main.log.error( self.name + ": " + self.handle.before )
2072 main.cleanup()
2073 main.exit()
2074 except Exception:
2075 main.log.exception( self.name + ": Uncaught exception!" )
2076 main.cleanup()
2077 main.exit()
2078
kelvin-onlab54400a92015-02-26 18:05:51 -08002079 def getIntentState(self, intentsId, intentsJson=None):
2080 """
You Wangfdcbfc42016-05-16 12:16:53 -07002081 Description:
2082 Gets intent state. Accepts a single intent ID (string type) or a
2083 list of intent IDs.
2084 Parameters:
2085 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002086 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002087 Returns:
2088 Returns the state (string type) of the ID if a single intent ID is
2089 accepted.
2090 Returns a list of dictionaries if a list of intent IDs is accepted,
2091 and each dictionary maps 'id' to the Intent ID and 'state' to
2092 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002094 try:
2095 state = "State is Undefined"
2096 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002097 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002098 else:
Jon Hallc6793552016-01-19 14:18:37 -08002099 rawJson = intentsJson
2100 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002101 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002102 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002103 if intentsId == intent[ 'id' ]:
2104 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002105 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002106 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2107 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002109 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002110 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002111 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002112 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002113 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002114 if intentsId[ i ] == intents[ 'id' ]:
2115 stateDict[ 'state' ] = intents[ 'state' ]
2116 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002117 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 break
Jon Hallefbd9792015-03-05 16:11:36 -08002119 if len( intentsId ) != len( dictList ):
2120 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002121 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002122 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002124 return None
Jon Hallc6793552016-01-19 14:18:37 -08002125 except ( TypeError, ValueError ):
2126 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002127 return None
2128 except pexpect.EOF:
2129 main.log.error( self.name + ": EOF exception found" )
2130 main.log.error( self.name + ": " + self.handle.before )
2131 main.cleanup()
2132 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002133 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002134 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002135 main.cleanup()
2136 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002137
kelvin-onlabf512e942015-06-08 19:42:59 -07002138 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002139 """
2140 Description:
2141 Check intents state
2142 Required:
2143 intentsId - List of intents ID to be checked
2144 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002145 expectedState - Check the expected state(s) of each intents
2146 state in the list.
2147 *NOTE: You can pass in a list of expected state,
2148 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002149 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002150 Returns main.TRUE only if all intent are the same as expected states
2151 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002152 """
2153 try:
2154 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002155 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002156 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002157 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002158 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002159 "getting intents state" )
2160 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002161
2162 if isinstance( expectedState, types.StringType ):
2163 for intents in intentsDict:
2164 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002165 main.log.debug( self.name + " : Intent ID - " +
2166 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002167 " actual state = " +
2168 intents.get( 'state' )
2169 + " does not equal expected state = "
2170 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002171 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002172
2173 elif isinstance( expectedState, types.ListType ):
2174 for intents in intentsDict:
2175 if not any( state == intents.get( 'state' ) for state in
2176 expectedState ):
2177 main.log.debug( self.name + " : Intent ID - " +
2178 intents.get( 'id' ) +
2179 " actual state = " +
2180 intents.get( 'state' ) +
2181 " does not equal expected states = "
2182 + str( expectedState ) )
2183 returnValue = main.FALSE
2184
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002185 if returnValue == main.TRUE:
2186 main.log.info( self.name + ": All " +
2187 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002188 " intents are in " + str( expectedState ) +
2189 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002190 return returnValue
2191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return None
2194 except pexpect.EOF:
2195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
2197 main.cleanup()
2198 main.exit()
2199 except Exception:
2200 main.log.exception( self.name + ": Uncaught exception!" )
2201 main.cleanup()
2202 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002203
You Wang66518af2016-05-16 15:32:59 -07002204 def compareIntent( self, intentDict ):
2205 """
2206 Description:
2207 Compare the intent ids and states provided in the argument with all intents in ONOS
2208 Return:
2209 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2210 Arguments:
2211 intentDict: a dictionary which maps intent ids to intent states
2212 """
2213 try:
2214 intentsRaw = self.intents()
2215 intentsJson = json.loads( intentsRaw )
2216 intentDictONOS = {}
2217 for intent in intentsJson:
2218 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002219 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002220 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002221 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002222 str( len( intentDict ) ) + " expected and " +
2223 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002224 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002225 for intentID in intentDict.keys():
2226 if not intentID in intentDictONOS.keys():
2227 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2228 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002229 else:
2230 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2231 main.log.debug( self.name + ": intent ID - " + intentID +
2232 " expected state is " + intentDict[ intentID ] +
2233 " but actual state is " + intentDictONOS[ intentID ] )
2234 returnValue = main.FALSE
2235 intentDictONOS.pop( intentID )
2236 if len( intentDictONOS ) > 0:
2237 returnValue = main.FALSE
2238 for intentID in intentDictONOS.keys():
2239 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002240 if returnValue == main.TRUE:
2241 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2242 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002243 except KeyError:
2244 main.log.exception( self.name + ": KeyError exception found" )
2245 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002246 except ( TypeError, ValueError ):
2247 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002248 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002249 except pexpect.EOF:
2250 main.log.error( self.name + ": EOF exception found" )
2251 main.log.error( self.name + ": " + self.handle.before )
2252 main.cleanup()
2253 main.exit()
2254 except Exception:
2255 main.log.exception( self.name + ": Uncaught exception!" )
2256 main.cleanup()
2257 main.exit()
2258
YPZhang14a4aa92016-07-15 13:37:15 -07002259 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002260 """
2261 Description:
2262 Check the number of installed intents.
2263 Optional:
2264 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002265 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002266 Return:
2267 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2268 , otherwise, returns main.FALSE.
2269 """
2270
2271 try:
2272 cmd = "intents -s -j"
2273
2274 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002275 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002276 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002277 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002278 response = json.loads( response )
2279
2280 # get total and installed number, see if they are match
2281 allState = response.get( 'all' )
2282 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002283 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002284 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002285 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002286 return main.FALSE
2287
Jon Hallc6793552016-01-19 14:18:37 -08002288 except ( TypeError, ValueError ):
2289 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002290 return None
2291 except pexpect.EOF:
2292 main.log.error( self.name + ": EOF exception found" )
2293 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002294 if noExit:
2295 return main.FALSE
2296 else:
2297 main.cleanup()
2298 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002299 except Exception:
2300 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002301 if noExit:
2302 return main.FALSE
2303 else:
2304 main.cleanup()
2305 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002306 except pexpect.TIMEOUT:
2307 main.log.error( self.name + ": ONOS timeout" )
2308 return None
GlennRCed771242016-01-13 17:02:47 -08002309
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002310 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002311 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002312 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002313 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002314 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002315 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002316 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002317 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002318 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002319 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002320 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002321 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002322 if noCore:
2323 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002324 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002325 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002326 assert "Command not found:" not in handle, handle
2327 if re.search( "Error:", handle ):
2328 main.log.error( self.name + ": flows() response: " +
2329 str( handle ) )
2330 return handle
2331 except AssertionError:
2332 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002333 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002334 except TypeError:
2335 main.log.exception( self.name + ": Object not as expected" )
2336 return None
Jon Hallc6793552016-01-19 14:18:37 -08002337 except pexpect.TIMEOUT:
2338 main.log.error( self.name + ": ONOS timeout" )
2339 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002340 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002341 main.log.error( self.name + ": EOF exception found" )
2342 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002343 main.cleanup()
2344 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002345 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002346 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002347 main.cleanup()
2348 main.exit()
2349
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002350 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002351 count = self.getTotalFlowsNum( timeout=timeout )
2352 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002353 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002354
YPZhangebf9eb52016-05-12 15:20:24 -07002355 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002356 """
2357 Description:
GlennRCed771242016-01-13 17:02:47 -08002358 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002359 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2360 if the count of those states is 0, which means all current flows
2361 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002362 Optional:
GlennRCed771242016-01-13 17:02:47 -08002363 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002364 Return:
2365 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002366 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002367 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002368 """
2369 try:
GlennRCed771242016-01-13 17:02:47 -08002370 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2371 checkedStates = []
2372 statesCount = [0, 0, 0, 0]
2373 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002374 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002375 if rawFlows:
2376 # if we didn't get flows or flows function return None, we should return
2377 # main.Flase
2378 checkedStates.append( json.loads( rawFlows ) )
2379 else:
2380 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002381 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002382 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002383 try:
2384 statesCount[i] += int( c.get( "flowCount" ) )
2385 except TypeError:
2386 main.log.exception( "Json object not as expected" )
2387 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002388
GlennRCed771242016-01-13 17:02:47 -08002389 # We want to count PENDING_ADD if isPENDING is true
2390 if isPENDING:
2391 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2392 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002393 else:
GlennRCed771242016-01-13 17:02:47 -08002394 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2395 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002396 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002397 except ( TypeError, ValueError ):
2398 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002399 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002400
YPZhang240842b2016-05-17 12:00:50 -07002401 except AssertionError:
2402 main.log.exception( "" )
2403 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002404 except pexpect.EOF:
2405 main.log.error( self.name + ": EOF exception found" )
2406 main.log.error( self.name + ": " + self.handle.before )
2407 main.cleanup()
2408 main.exit()
2409 except Exception:
2410 main.log.exception( self.name + ": Uncaught exception!" )
2411 main.cleanup()
2412 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002413 except pexpect.TIMEOUT:
2414 main.log.error( self.name + ": ONOS timeout" )
2415 return None
2416
kelvin-onlab4df89f22015-04-13 18:10:23 -07002417
GlennRCed771242016-01-13 17:02:47 -08002418 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002419 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002420 """
andrewonlab87852b02014-11-19 18:44:19 -05002421 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002422 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002423 a specific point-to-point intent definition
2424 Required:
GlennRCed771242016-01-13 17:02:47 -08002425 * ingress: specify source dpid
2426 * egress: specify destination dpid
2427 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002428 Optional:
GlennRCed771242016-01-13 17:02:47 -08002429 * offset: the keyOffset is where the next batch of intents
2430 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002431 * noExit: If set to True, TestON will not exit if any error when issus command
2432 * getResponse: If set to True, function will return ONOS response.
2433
GlennRCed771242016-01-13 17:02:47 -08002434 Returns: If failed to push test intents, it will returen None,
2435 if successful, return true.
2436 Timeout expection will return None,
2437 TypeError will return false
2438 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002439 """
andrewonlab87852b02014-11-19 18:44:19 -05002440 try:
GlennRCed771242016-01-13 17:02:47 -08002441 if background:
2442 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002443 else:
GlennRCed771242016-01-13 17:02:47 -08002444 back = ""
2445 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002446 ingress,
2447 egress,
2448 batchSize,
2449 offset,
2450 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002451 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002452 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002453 main.log.info( response )
2454 if response == None:
2455 return None
2456
YPZhangb34b7e12016-06-14 14:28:19 -07002457 if getResponse:
2458 return response
2459
GlennRCed771242016-01-13 17:02:47 -08002460 # TODO: We should handle if there is failure in installation
2461 return main.TRUE
2462
Jon Hallc6793552016-01-19 14:18:37 -08002463 except AssertionError:
2464 main.log.exception( "" )
2465 return None
GlennRCed771242016-01-13 17:02:47 -08002466 except pexpect.TIMEOUT:
2467 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002468 return None
andrewonlab87852b02014-11-19 18:44:19 -05002469 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002470 main.log.error( self.name + ": EOF exception found" )
2471 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002472 main.cleanup()
2473 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002474 except TypeError:
2475 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002476 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002477 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002478 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002479 main.cleanup()
2480 main.exit()
2481
YPZhangebf9eb52016-05-12 15:20:24 -07002482 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002483 """
2484 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002485 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002486 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002487 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002488 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002489 """
YPZhange3109a72016-02-02 11:25:37 -08002490
YPZhangb5d3f832016-01-23 22:54:26 -08002491 try:
YPZhange3109a72016-02-02 11:25:37 -08002492 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002493 cmd = "flows -c added"
2494 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2495 if rawFlows:
2496 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002497 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002498 for l in rawFlows:
2499 totalFlows += int(l.split("Count=")[1])
2500 else:
2501 main.log.error("Response not as expected!")
2502 return None
2503 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002504
You Wangd3cb2ce2016-05-16 14:01:24 -07002505 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002506 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002507 return None
2508 except pexpect.EOF:
2509 main.log.error( self.name + ": EOF exception found" )
2510 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002511 if not noExit:
2512 main.cleanup()
2513 main.exit()
2514 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002515 except Exception:
2516 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002517 if not noExit:
2518 main.cleanup()
2519 main.exit()
2520 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002521 except pexpect.TIMEOUT:
2522 main.log.error( self.name + ": ONOS timeout" )
2523 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002524
YPZhang14a4aa92016-07-15 13:37:15 -07002525 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002526 """
2527 Description:
2528 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002529 Optional:
2530 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002531 Return:
2532 The number of intents
2533 """
2534 try:
2535 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002536 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002537 if response == None:
2538 return -1
2539 response = json.loads( response )
2540 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002541 except ( TypeError, ValueError ):
2542 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002543 return None
2544 except pexpect.EOF:
2545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002547 if noExit:
2548 return -1
2549 else:
2550 main.cleanup()
2551 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002552 except Exception:
2553 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002554 if noExit:
2555 return -1
2556 else:
2557 main.cleanup()
2558 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002559
kelvin-onlabd3b64892015-01-20 13:26:24 -08002560 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002561 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002562 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002563 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002564 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002565 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002566 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002567 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002569 cmdStr += " -j"
2570 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002571 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002572 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002573 except AssertionError:
2574 main.log.exception( "" )
2575 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002576 except TypeError:
2577 main.log.exception( self.name + ": Object not as expected" )
2578 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002579 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002580 main.log.error( self.name + ": EOF exception found" )
2581 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002582 main.cleanup()
2583 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002584 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002585 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002586 main.cleanup()
2587 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002588
kelvin-onlabd3b64892015-01-20 13:26:24 -08002589 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002590 """
2591 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002592 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002594 """
andrewonlab867212a2014-10-22 20:13:38 -04002595 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002596 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002598 cmdStr += " -j"
2599 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002600 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002601 if handle:
2602 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002603 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002604 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002605 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002606 else:
2607 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002608 except AssertionError:
2609 main.log.exception( "" )
2610 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002611 except TypeError:
2612 main.log.exception( self.name + ": Object not as expected" )
2613 return None
andrewonlab867212a2014-10-22 20:13:38 -04002614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002615 main.log.error( self.name + ": EOF exception found" )
2616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002617 main.cleanup()
2618 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002621 main.cleanup()
2622 main.exit()
2623
kelvin8ec71442015-01-15 16:57:00 -08002624 # Wrapper functions ****************
2625 # Wrapper functions use existing driver
2626 # functions and extends their use case.
2627 # For example, we may use the output of
2628 # a normal driver function, and parse it
2629 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002630
kelvin-onlabd3b64892015-01-20 13:26:24 -08002631 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002632 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002633 Description:
2634 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002635 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002636 try:
kelvin8ec71442015-01-15 16:57:00 -08002637 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002638 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002639 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002640
kelvin8ec71442015-01-15 16:57:00 -08002641 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002642 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2643 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002644 match = re.search('id=0x([\da-f]+),', intents)
2645 if match:
2646 tmpId = match.group()[3:-1]
2647 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002649
Jon Halld4d4b372015-01-28 16:02:41 -08002650 except TypeError:
2651 main.log.exception( self.name + ": Object not as expected" )
2652 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002654 main.log.error( self.name + ": EOF exception found" )
2655 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002656 main.cleanup()
2657 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002658 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002659 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002660 main.cleanup()
2661 main.exit()
2662
You Wang3c276252016-09-21 15:21:36 -07002663 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002664 """
2665 Determine the number of flow rules for the given device id that are
2666 in the added state
You Wang3c276252016-09-21 15:21:36 -07002667 Params:
2668 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002669 """
2670 try:
You Wang3c276252016-09-21 15:21:36 -07002671 if core:
2672 cmdStr = "flows any " + str( deviceId ) + " | " +\
2673 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2674 else:
2675 cmdStr = "flows any " + str( deviceId ) + " | " +\
2676 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002677 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002678 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002679 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002680 except AssertionError:
2681 main.log.exception( "" )
2682 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002683 except pexpect.EOF:
2684 main.log.error( self.name + ": EOF exception found" )
2685 main.log.error( self.name + ": " + self.handle.before )
2686 main.cleanup()
2687 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002688 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002689 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002690 main.cleanup()
2691 main.exit()
2692
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002694 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002695 Use 'devices' function to obtain list of all devices
2696 and parse the result to obtain a list of all device
2697 id's. Returns this list. Returns empty list if no
2698 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002699 List is ordered sequentially
2700
andrewonlab3e15ead2014-10-15 14:21:34 -04002701 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002702 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002703 the ids. By obtaining the list of device ids on the fly,
2704 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002705 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002706 try:
kelvin8ec71442015-01-15 16:57:00 -08002707 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002708 devicesStr = self.devices( jsonFormat=False )
2709 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002710
kelvin-onlabd3b64892015-01-20 13:26:24 -08002711 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002712 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002713 return idList
kelvin8ec71442015-01-15 16:57:00 -08002714
2715 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002717 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002719 # Split list further into arguments before and after string
2720 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 # append to idList
2722 for arg in tempList:
2723 idList.append( arg.split( "id=" )[ 1 ] )
2724 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002725
Jon Halld4d4b372015-01-28 16:02:41 -08002726 except TypeError:
2727 main.log.exception( self.name + ": Object not as expected" )
2728 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002730 main.log.error( self.name + ": EOF exception found" )
2731 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002732 main.cleanup()
2733 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002735 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002736 main.cleanup()
2737 main.exit()
2738
kelvin-onlabd3b64892015-01-20 13:26:24 -08002739 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002740 """
andrewonlab7c211572014-10-15 16:45:20 -04002741 Uses 'nodes' function to obtain list of all nodes
2742 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002743 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002744 Returns:
2745 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002746 """
andrewonlab7c211572014-10-15 16:45:20 -04002747 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002748 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002749 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002750 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002751 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002752 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002753 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002755 nodesJson = json.loads( nodesStr )
2756 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002758 except ( TypeError, ValueError ):
2759 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002760 return None
andrewonlab7c211572014-10-15 16:45:20 -04002761 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002762 main.log.error( self.name + ": EOF exception found" )
2763 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002764 main.cleanup()
2765 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002766 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002767 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002768 main.cleanup()
2769 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002770
kelvin-onlabd3b64892015-01-20 13:26:24 -08002771 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002772 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002773 Return the first device from the devices api whose 'id' contains 'dpid'
2774 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002775 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002776 try:
kelvin8ec71442015-01-15 16:57:00 -08002777 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002778 return None
2779 else:
kelvin8ec71442015-01-15 16:57:00 -08002780 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 rawDevices = self.devices()
2782 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002783 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002784 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002785 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2786 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002787 return device
2788 return None
Jon Hallc6793552016-01-19 14:18:37 -08002789 except ( TypeError, ValueError ):
2790 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002791 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002792 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002793 main.log.error( self.name + ": EOF exception found" )
2794 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002795 main.cleanup()
2796 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002797 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002798 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002799 main.cleanup()
2800 main.exit()
2801
You Wang24139872016-05-03 11:48:47 -07002802 def getTopology( self, topologyOutput ):
2803 """
2804 Definition:
2805 Loads a json topology output
2806 Return:
2807 topology = current ONOS topology
2808 """
2809 import json
2810 try:
2811 # either onos:topology or 'topology' will work in CLI
2812 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002813 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002814 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002815 except ( TypeError, ValueError ):
2816 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2817 return None
You Wang24139872016-05-03 11:48:47 -07002818 except pexpect.EOF:
2819 main.log.error( self.name + ": EOF exception found" )
2820 main.log.error( self.name + ": " + self.handle.before )
2821 main.cleanup()
2822 main.exit()
2823 except Exception:
2824 main.log.exception( self.name + ": Uncaught exception!" )
2825 main.cleanup()
2826 main.exit()
2827
Flavio Castro82ee2f62016-06-07 15:04:12 -07002828 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002829 """
Jon Hallefbd9792015-03-05 16:11:36 -08002830 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002831 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002832 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002833
Flavio Castro82ee2f62016-06-07 15:04:12 -07002834 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002835 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002836 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002837 logLevel = level to log to.
2838 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002839
Jon Hallefbd9792015-03-05 16:11:36 -08002840 Returns: main.TRUE if the number of switches and links are correct,
2841 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002842 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002843 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002844 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002845 try:
You Wang13310252016-07-31 10:56:14 -07002846 summary = self.summary()
2847 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002848 except ( TypeError, ValueError ):
2849 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2850 return main.ERROR
2851 try:
2852 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002853 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002854 return main.ERROR
2855 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002856 # Is the number of switches is what we expected
2857 devices = topology.get( 'devices', False )
2858 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002859 nodes = summary.get( 'nodes', False )
2860 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002861 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002862 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002863 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002864 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002865 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2866 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002867 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002868 output = output + "The number of links and switches match "\
2869 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002870 result = main.TRUE
2871 else:
You Wang24139872016-05-03 11:48:47 -07002872 output = output + \
2873 "The number of links and switches does not match " + \
2874 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002875 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002876 output = output + "\n ONOS sees %i devices" % int( devices )
2877 output = output + " (%i expected) " % int( numoswitch )
2878 output = output + "and %i links " % int( links )
2879 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002880 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002881 output = output + "and %i controllers " % int( nodes )
2882 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002883 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002884 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002886 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002887 else:
You Wang24139872016-05-03 11:48:47 -07002888 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002889 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002891 main.log.error( self.name + ": EOF exception found" )
2892 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002893 main.cleanup()
2894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002897 main.cleanup()
2898 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002899
kelvin-onlabd3b64892015-01-20 13:26:24 -08002900 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002901 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002902 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 deviceId must be the id of a device as seen in the onos devices command
2904 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002905 role must be either master, standby, or none
2906
Jon Halle3f39ff2015-01-13 11:50:53 -08002907 Returns:
2908 main.TRUE or main.FALSE based on argument verification and
2909 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002910 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002911 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002912 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002913 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002914 cmdStr = "device-role " +\
2915 str( deviceId ) + " " +\
2916 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002917 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002919 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002920 if re.search( "Error", handle ):
2921 # end color output to escape any colours
2922 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002923 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002924 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002925 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002926 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002927 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 main.log.error( "Invalid 'role' given to device_role(). " +
2929 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002930 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002931 except AssertionError:
2932 main.log.exception( "" )
2933 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002934 except TypeError:
2935 main.log.exception( self.name + ": Object not as expected" )
2936 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002937 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002938 main.log.error( self.name + ": EOF exception found" )
2939 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002940 main.cleanup()
2941 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002942 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002943 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002944 main.cleanup()
2945 main.exit()
2946
kelvin-onlabd3b64892015-01-20 13:26:24 -08002947 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002948 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002949 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002950 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002952 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002953 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002954 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002956 cmdStr += " -j"
2957 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002958 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002959 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002960 except AssertionError:
2961 main.log.exception( "" )
2962 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002963 except TypeError:
2964 main.log.exception( self.name + ": Object not as expected" )
2965 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002966 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002967 main.log.error( self.name + ": EOF exception found" )
2968 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002969 main.cleanup()
2970 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002971 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002972 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002973 main.cleanup()
2974 main.exit()
2975
kelvin-onlabd3b64892015-01-20 13:26:24 -08002976 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002977 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002978 CLI command to get the current leader for the Election test application
2979 NOTE: Requires installation of the onos-app-election feature
2980 Returns: Node IP of the leader if one exists
2981 None if none exists
2982 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002983 """
Jon Hall94fd0472014-12-08 11:52:42 -08002984 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 cmdStr = "election-test-leader"
2986 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002987 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002988 # Leader
2989 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002990 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002991 nodeSearch = re.search( leaderPattern, response )
2992 if nodeSearch:
2993 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002994 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002995 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002996 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002997 # no leader
2998 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002999 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003000 nullSearch = re.search( nullPattern, response )
3001 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003002 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003004 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003006 main.log.error( "Error in electionTestLeader on " + self.name +
3007 ": " + "unexpected response" )
3008 main.log.error( repr( response ) )
3009 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003010 except AssertionError:
3011 main.log.exception( "" )
3012 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003013 except TypeError:
3014 main.log.exception( self.name + ": Object not as expected" )
3015 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003016 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003017 main.log.error( self.name + ": EOF exception found" )
3018 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003019 main.cleanup()
3020 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003021 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003022 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003023 main.cleanup()
3024 main.exit()
3025
kelvin-onlabd3b64892015-01-20 13:26:24 -08003026 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003027 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003028 CLI command to run for leadership of the Election test application.
3029 NOTE: Requires installation of the onos-app-election feature
3030 Returns: Main.TRUE on success
3031 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 """
Jon Hall94fd0472014-12-08 11:52:42 -08003033 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003034 cmdStr = "election-test-run"
3035 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003036 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003038 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003039 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003041 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003042 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003044 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003045 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003046 main.log.error( "Error in electionTestRun on " + self.name +
3047 ": " + "unexpected response" )
3048 main.log.error( repr( response ) )
3049 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003050 except AssertionError:
3051 main.log.exception( "" )
3052 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003053 except TypeError:
3054 main.log.exception( self.name + ": Object not as expected" )
3055 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003056 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003057 main.log.error( self.name + ": EOF exception found" )
3058 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003059 main.cleanup()
3060 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003061 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003062 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003063 main.cleanup()
3064 main.exit()
3065
kelvin-onlabd3b64892015-01-20 13:26:24 -08003066 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003067 """
Jon Hall94fd0472014-12-08 11:52:42 -08003068 * CLI command to withdraw the local node from leadership election for
3069 * the Election test application.
3070 #NOTE: Requires installation of the onos-app-election feature
3071 Returns: Main.TRUE on success
3072 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003073 """
Jon Hall94fd0472014-12-08 11:52:42 -08003074 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003075 cmdStr = "election-test-withdraw"
3076 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003077 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003078 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003079 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003080 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003081 if re.search( successPattern, response ):
3082 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003083 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003084 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003085 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003086 main.log.error( "Error in electionTestWithdraw on " +
3087 self.name + ": " + "unexpected response" )
3088 main.log.error( repr( response ) )
3089 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003090 except AssertionError:
3091 main.log.exception( "" )
3092 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003093 except TypeError:
3094 main.log.exception( self.name + ": Object not as expected" )
3095 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003096 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003097 main.log.error( self.name + ": EOF exception found" )
3098 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003099 main.cleanup()
3100 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003101 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003102 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003103 main.cleanup()
3104 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003105
kelvin8ec71442015-01-15 16:57:00 -08003106 def getDevicePortsEnabledCount( self, dpid ):
3107 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003108 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003110 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003111 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003112 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3113 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003114 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003115 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 if re.search( "No such device", output ):
3117 main.log.error( "Error in getting ports" )
3118 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003119 return output
Jon Hallc6793552016-01-19 14:18:37 -08003120 except AssertionError:
3121 main.log.exception( "" )
3122 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003123 except TypeError:
3124 main.log.exception( self.name + ": Object not as expected" )
3125 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003129 main.cleanup()
3130 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003132 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003133 main.cleanup()
3134 main.exit()
3135
kelvin8ec71442015-01-15 16:57:00 -08003136 def getDeviceLinksActiveCount( self, dpid ):
3137 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003138 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003139 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003140 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003142 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3143 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003144 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003145 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003146 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003147 main.log.error( "Error in getting ports " )
3148 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003149 return output
Jon Hallc6793552016-01-19 14:18:37 -08003150 except AssertionError:
3151 main.log.exception( "" )
3152 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003153 except TypeError:
3154 main.log.exception( self.name + ": Object not as expected" )
3155 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003157 main.log.error( self.name + ": EOF exception found" )
3158 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003159 main.cleanup()
3160 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003161 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003162 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003163 main.cleanup()
3164 main.exit()
3165
kelvin8ec71442015-01-15 16:57:00 -08003166 def getAllIntentIds( self ):
3167 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003168 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003169 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003170 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 cmdStr = "onos:intents | grep id="
3172 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003173 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003174 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003175 if re.search( "Error", output ):
3176 main.log.error( "Error in getting ports" )
3177 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003178 return output
Jon Hallc6793552016-01-19 14:18:37 -08003179 except AssertionError:
3180 main.log.exception( "" )
3181 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003182 except TypeError:
3183 main.log.exception( self.name + ": Object not as expected" )
3184 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003186 main.log.error( self.name + ": EOF exception found" )
3187 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003188 main.cleanup()
3189 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003191 main.log.exception( self.name + ": Uncaught exception!" )
3192 main.cleanup()
3193 main.exit()
3194
Jon Hall73509952015-02-24 16:42:56 -08003195 def intentSummary( self ):
3196 """
Jon Hallefbd9792015-03-05 16:11:36 -08003197 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003198 """
3199 try:
3200 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003201 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003202 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003203 states.append( intent.get( 'state', None ) )
3204 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003205 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003206 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003207 except ( TypeError, ValueError ):
3208 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003209 return None
3210 except pexpect.EOF:
3211 main.log.error( self.name + ": EOF exception found" )
3212 main.log.error( self.name + ": " + self.handle.before )
3213 main.cleanup()
3214 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003215 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003216 main.log.exception( self.name + ": Uncaught exception!" )
3217 main.cleanup()
3218 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003219
Jon Hall61282e32015-03-19 11:34:11 -07003220 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003221 """
3222 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003223 Optional argument:
3224 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003225 """
Jon Hall63604932015-02-26 17:09:50 -08003226 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003227 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003228 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003229 cmdStr += " -j"
3230 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003231 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003232 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003233 return output
Jon Hallc6793552016-01-19 14:18:37 -08003234 except AssertionError:
3235 main.log.exception( "" )
3236 return None
Jon Hall63604932015-02-26 17:09:50 -08003237 except TypeError:
3238 main.log.exception( self.name + ": Object not as expected" )
3239 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003240 except pexpect.EOF:
3241 main.log.error( self.name + ": EOF exception found" )
3242 main.log.error( self.name + ": " + self.handle.before )
3243 main.cleanup()
3244 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003245 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003246 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003247 main.cleanup()
3248 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003249
acsmarsa4a4d1e2015-07-10 16:01:24 -07003250 def leaderCandidates( self, jsonFormat=True ):
3251 """
3252 Returns the output of the leaders -c command.
3253 Optional argument:
3254 * jsonFormat - boolean indicating if you want output in json
3255 """
3256 try:
3257 cmdStr = "onos:leaders -c"
3258 if jsonFormat:
3259 cmdStr += " -j"
3260 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003261 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003262 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003263 return output
Jon Hallc6793552016-01-19 14:18:37 -08003264 except AssertionError:
3265 main.log.exception( "" )
3266 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003267 except TypeError:
3268 main.log.exception( self.name + ": Object not as expected" )
3269 return None
3270 except pexpect.EOF:
3271 main.log.error( self.name + ": EOF exception found" )
3272 main.log.error( self.name + ": " + self.handle.before )
3273 main.cleanup()
3274 main.exit()
3275 except Exception:
3276 main.log.exception( self.name + ": Uncaught exception!" )
3277 main.cleanup()
3278 main.exit()
3279
Jon Hallc6793552016-01-19 14:18:37 -08003280 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003281 """
3282 Returns a list in format [leader,candidate1,candidate2,...] for a given
3283 topic parameter and an empty list if the topic doesn't exist
3284 If no leader is elected leader in the returned list will be "none"
3285 Returns None if there is a type error processing the json object
3286 """
3287 try:
Jon Hall6e709752016-02-01 13:38:46 -08003288 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003289 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003290 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003291 assert "Command not found:" not in rawOutput, rawOutput
3292 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003293 results = []
3294 for dict in output:
3295 if dict["topic"] == topic:
3296 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003297 candidates = re.split( ", ", dict["candidates"][1:-1] )
3298 results.append( leader )
3299 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003300 return results
Jon Hallc6793552016-01-19 14:18:37 -08003301 except AssertionError:
3302 main.log.exception( "" )
3303 return None
3304 except ( TypeError, ValueError ):
3305 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003306 return None
3307 except pexpect.EOF:
3308 main.log.error( self.name + ": EOF exception found" )
3309 main.log.error( self.name + ": " + self.handle.before )
3310 main.cleanup()
3311 main.exit()
3312 except Exception:
3313 main.log.exception( self.name + ": Uncaught exception!" )
3314 main.cleanup()
3315 main.exit()
3316
Jon Hall61282e32015-03-19 11:34:11 -07003317 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003318 """
3319 Returns the output of the intent Pending map.
3320 """
Jon Hall63604932015-02-26 17:09:50 -08003321 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003322 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003323 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003324 cmdStr += " -j"
3325 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003326 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003327 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003328 return output
Jon Hallc6793552016-01-19 14:18:37 -08003329 except AssertionError:
3330 main.log.exception( "" )
3331 return None
Jon Hall63604932015-02-26 17:09:50 -08003332 except TypeError:
3333 main.log.exception( self.name + ": Object not as expected" )
3334 return None
3335 except pexpect.EOF:
3336 main.log.error( self.name + ": EOF exception found" )
3337 main.log.error( self.name + ": " + self.handle.before )
3338 main.cleanup()
3339 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003340 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003341 main.log.exception( self.name + ": Uncaught exception!" )
3342 main.cleanup()
3343 main.exit()
3344
Jon Hall61282e32015-03-19 11:34:11 -07003345 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003346 """
3347 Returns the output of the raft partitions command for ONOS.
3348 """
Jon Hall61282e32015-03-19 11:34:11 -07003349 # Sample JSON
3350 # {
3351 # "leader": "tcp://10.128.30.11:7238",
3352 # "members": [
3353 # "tcp://10.128.30.11:7238",
3354 # "tcp://10.128.30.17:7238",
3355 # "tcp://10.128.30.13:7238",
3356 # ],
3357 # "name": "p1",
3358 # "term": 3
3359 # },
Jon Hall63604932015-02-26 17:09:50 -08003360 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003361 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003362 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003363 cmdStr += " -j"
3364 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003365 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003366 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003367 return output
Jon Hallc6793552016-01-19 14:18:37 -08003368 except AssertionError:
3369 main.log.exception( "" )
3370 return None
Jon Hall63604932015-02-26 17:09:50 -08003371 except TypeError:
3372 main.log.exception( self.name + ": Object not as expected" )
3373 return None
3374 except pexpect.EOF:
3375 main.log.error( self.name + ": EOF exception found" )
3376 main.log.error( self.name + ": " + self.handle.before )
3377 main.cleanup()
3378 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003379 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003380 main.log.exception( self.name + ": Uncaught exception!" )
3381 main.cleanup()
3382 main.exit()
3383
Jon Halle9f909e2016-09-23 10:43:12 -07003384 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003385 """
3386 Returns the output of the apps command for ONOS. This command lists
3387 information about installed ONOS applications
3388 """
3389 # Sample JSON object
3390 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3391 # "description":"ONOS OpenFlow protocol southbound providers",
3392 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3393 # "features":"[onos-openflow]","state":"ACTIVE"}]
3394 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003395 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003396 if summary:
3397 cmdStr += " -s"
3398 if active:
3399 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003400 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003401 cmdStr += " -j"
3402 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003403 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003404 assert "Command not found:" not in output, output
3405 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003406 return output
Jon Hallbe379602015-03-24 13:39:32 -07003407 # FIXME: look at specific exceptions/Errors
3408 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003409 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003410 return None
3411 except TypeError:
3412 main.log.exception( self.name + ": Object not as expected" )
3413 return None
3414 except pexpect.EOF:
3415 main.log.error( self.name + ": EOF exception found" )
3416 main.log.error( self.name + ": " + self.handle.before )
3417 main.cleanup()
3418 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003419 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003420 main.log.exception( self.name + ": Uncaught exception!" )
3421 main.cleanup()
3422 main.exit()
3423
Jon Hall146f1522015-03-24 15:33:24 -07003424 def appStatus( self, appName ):
3425 """
3426 Uses the onos:apps cli command to return the status of an application.
3427 Returns:
3428 "ACTIVE" - If app is installed and activated
3429 "INSTALLED" - If app is installed and deactivated
3430 "UNINSTALLED" - If app is not installed
3431 None - on error
3432 """
Jon Hall146f1522015-03-24 15:33:24 -07003433 try:
3434 if not isinstance( appName, types.StringType ):
3435 main.log.error( self.name + ".appStatus(): appName must be" +
3436 " a string" )
3437 return None
3438 output = self.apps( jsonFormat=True )
3439 appsJson = json.loads( output )
3440 state = None
3441 for app in appsJson:
3442 if appName == app.get('name'):
3443 state = app.get('state')
3444 break
3445 if state == "ACTIVE" or state == "INSTALLED":
3446 return state
3447 elif state is None:
3448 return "UNINSTALLED"
3449 elif state:
3450 main.log.error( "Unexpected state from 'onos:apps': " +
3451 str( state ) )
3452 return state
Jon Hallc6793552016-01-19 14:18:37 -08003453 except ( TypeError, ValueError ):
3454 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003455 return None
3456 except pexpect.EOF:
3457 main.log.error( self.name + ": EOF exception found" )
3458 main.log.error( self.name + ": " + self.handle.before )
3459 main.cleanup()
3460 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003461 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003462 main.log.exception( self.name + ": Uncaught exception!" )
3463 main.cleanup()
3464 main.exit()
3465
Jon Hallbe379602015-03-24 13:39:32 -07003466 def app( self, appName, option ):
3467 """
3468 Interacts with the app command for ONOS. This command manages
3469 application inventory.
3470 """
Jon Hallbe379602015-03-24 13:39:32 -07003471 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003472 # Validate argument types
3473 valid = True
3474 if not isinstance( appName, types.StringType ):
3475 main.log.error( self.name + ".app(): appName must be a " +
3476 "string" )
3477 valid = False
3478 if not isinstance( option, types.StringType ):
3479 main.log.error( self.name + ".app(): option must be a string" )
3480 valid = False
3481 if not valid:
3482 return main.FALSE
3483 # Validate Option
3484 option = option.lower()
3485 # NOTE: Install may become a valid option
3486 if option == "activate":
3487 pass
3488 elif option == "deactivate":
3489 pass
3490 elif option == "uninstall":
3491 pass
3492 else:
3493 # Invalid option
3494 main.log.error( "The ONOS app command argument only takes " +
3495 "the values: (activate|deactivate|uninstall)" +
3496 "; was given '" + option + "'")
3497 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003498 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003499 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003500 if "Error executing command" in output:
3501 main.log.error( "Error in processing onos:app command: " +
3502 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003503 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003504 elif "No such application" in output:
3505 main.log.error( "The application '" + appName +
3506 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003507 return main.FALSE
3508 elif "Command not found:" in output:
3509 main.log.error( "Error in processing onos:app command: " +
3510 str( output ) )
3511 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003512 elif "Unsupported command:" in output:
3513 main.log.error( "Incorrect command given to 'app': " +
3514 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003515 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003516 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003517 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003518 return main.TRUE
3519 except TypeError:
3520 main.log.exception( self.name + ": Object not as expected" )
3521 return main.ERROR
3522 except pexpect.EOF:
3523 main.log.error( self.name + ": EOF exception found" )
3524 main.log.error( self.name + ": " + self.handle.before )
3525 main.cleanup()
3526 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003527 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003528 main.log.exception( self.name + ": Uncaught exception!" )
3529 main.cleanup()
3530 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003531
Jon Hallbd16b922015-03-26 17:53:15 -07003532 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003533 """
3534 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003535 appName is the hierarchical app name, not the feature name
3536 If check is True, method will check the status of the app after the
3537 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003538 Returns main.TRUE if the command was successfully sent
3539 main.FALSE if the cli responded with an error or given
3540 incorrect input
3541 """
3542 try:
3543 if not isinstance( appName, types.StringType ):
3544 main.log.error( self.name + ".activateApp(): appName must be" +
3545 " a string" )
3546 return main.FALSE
3547 status = self.appStatus( appName )
3548 if status == "INSTALLED":
3549 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003550 if check and response == main.TRUE:
3551 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003552 status = self.appStatus( appName )
3553 if status == "ACTIVE":
3554 return main.TRUE
3555 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003556 main.log.debug( "The state of application " +
3557 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003558 time.sleep( 1 )
3559 return main.FALSE
3560 else: # not 'check' or command didn't succeed
3561 return response
Jon Hall146f1522015-03-24 15:33:24 -07003562 elif status == "ACTIVE":
3563 return main.TRUE
3564 elif status == "UNINSTALLED":
3565 main.log.error( self.name + ": Tried to activate the " +
3566 "application '" + appName + "' which is not " +
3567 "installed." )
3568 else:
3569 main.log.error( "Unexpected return value from appStatus: " +
3570 str( status ) )
3571 return main.ERROR
3572 except TypeError:
3573 main.log.exception( self.name + ": Object not as expected" )
3574 return main.ERROR
3575 except pexpect.EOF:
3576 main.log.error( self.name + ": EOF exception found" )
3577 main.log.error( self.name + ": " + self.handle.before )
3578 main.cleanup()
3579 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003580 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003581 main.log.exception( self.name + ": Uncaught exception!" )
3582 main.cleanup()
3583 main.exit()
3584
Jon Hallbd16b922015-03-26 17:53:15 -07003585 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003586 """
3587 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003588 appName is the hierarchical app name, not the feature name
3589 If check is True, method will check the status of the app after the
3590 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003591 Returns main.TRUE if the command was successfully sent
3592 main.FALSE if the cli responded with an error or given
3593 incorrect input
3594 """
3595 try:
3596 if not isinstance( appName, types.StringType ):
3597 main.log.error( self.name + ".deactivateApp(): appName must " +
3598 "be a string" )
3599 return main.FALSE
3600 status = self.appStatus( appName )
3601 if status == "INSTALLED":
3602 return main.TRUE
3603 elif status == "ACTIVE":
3604 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003605 if check and response == main.TRUE:
3606 for i in range(10): # try 10 times then give up
3607 status = self.appStatus( appName )
3608 if status == "INSTALLED":
3609 return main.TRUE
3610 else:
3611 time.sleep( 1 )
3612 return main.FALSE
3613 else: # not check or command didn't succeed
3614 return response
Jon Hall146f1522015-03-24 15:33:24 -07003615 elif status == "UNINSTALLED":
3616 main.log.warn( self.name + ": Tried to deactivate the " +
3617 "application '" + appName + "' which is not " +
3618 "installed." )
3619 return main.TRUE
3620 else:
3621 main.log.error( "Unexpected return value from appStatus: " +
3622 str( status ) )
3623 return main.ERROR
3624 except TypeError:
3625 main.log.exception( self.name + ": Object not as expected" )
3626 return main.ERROR
3627 except pexpect.EOF:
3628 main.log.error( self.name + ": EOF exception found" )
3629 main.log.error( self.name + ": " + self.handle.before )
3630 main.cleanup()
3631 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003632 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003633 main.log.exception( self.name + ": Uncaught exception!" )
3634 main.cleanup()
3635 main.exit()
3636
Jon Hallbd16b922015-03-26 17:53:15 -07003637 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003638 """
3639 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003640 appName is the hierarchical app name, not the feature name
3641 If check is True, method will check the status of the app after the
3642 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003643 Returns main.TRUE if the command was successfully sent
3644 main.FALSE if the cli responded with an error or given
3645 incorrect input
3646 """
3647 # TODO: check with Thomas about the state machine for apps
3648 try:
3649 if not isinstance( appName, types.StringType ):
3650 main.log.error( self.name + ".uninstallApp(): appName must " +
3651 "be a string" )
3652 return main.FALSE
3653 status = self.appStatus( appName )
3654 if status == "INSTALLED":
3655 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003656 if check and response == main.TRUE:
3657 for i in range(10): # try 10 times then give up
3658 status = self.appStatus( appName )
3659 if status == "UNINSTALLED":
3660 return main.TRUE
3661 else:
3662 time.sleep( 1 )
3663 return main.FALSE
3664 else: # not check or command didn't succeed
3665 return response
Jon Hall146f1522015-03-24 15:33:24 -07003666 elif status == "ACTIVE":
3667 main.log.warn( self.name + ": Tried to uninstall the " +
3668 "application '" + appName + "' which is " +
3669 "currently active." )
3670 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003671 if check and response == main.TRUE:
3672 for i in range(10): # try 10 times then give up
3673 status = self.appStatus( appName )
3674 if status == "UNINSTALLED":
3675 return main.TRUE
3676 else:
3677 time.sleep( 1 )
3678 return main.FALSE
3679 else: # not check or command didn't succeed
3680 return response
Jon Hall146f1522015-03-24 15:33:24 -07003681 elif status == "UNINSTALLED":
3682 return main.TRUE
3683 else:
3684 main.log.error( "Unexpected return value from appStatus: " +
3685 str( status ) )
3686 return main.ERROR
3687 except TypeError:
3688 main.log.exception( self.name + ": Object not as expected" )
3689 return main.ERROR
3690 except pexpect.EOF:
3691 main.log.error( self.name + ": EOF exception found" )
3692 main.log.error( self.name + ": " + self.handle.before )
3693 main.cleanup()
3694 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003695 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003696 main.log.exception( self.name + ": Uncaught exception!" )
3697 main.cleanup()
3698 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003699
3700 def appIDs( self, jsonFormat=True ):
3701 """
3702 Show the mappings between app id and app names given by the 'app-ids'
3703 cli command
3704 """
3705 try:
3706 cmdStr = "app-ids"
3707 if jsonFormat:
3708 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003709 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003710 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003711 assert "Command not found:" not in output, output
3712 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003713 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003714 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003715 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003716 return None
3717 except TypeError:
3718 main.log.exception( self.name + ": Object not as expected" )
3719 return None
3720 except pexpect.EOF:
3721 main.log.error( self.name + ": EOF exception found" )
3722 main.log.error( self.name + ": " + self.handle.before )
3723 main.cleanup()
3724 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003725 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003726 main.log.exception( self.name + ": Uncaught exception!" )
3727 main.cleanup()
3728 main.exit()
3729
3730 def appToIDCheck( self ):
3731 """
3732 This method will check that each application's ID listed in 'apps' is
3733 the same as the ID listed in 'app-ids'. The check will also check that
3734 there are no duplicate IDs issued. Note that an app ID should be
3735 a globaly unique numerical identifier for app/app-like features. Once
3736 an ID is registered, the ID is never freed up so that if an app is
3737 reinstalled it will have the same ID.
3738
3739 Returns: main.TRUE if the check passes and
3740 main.FALSE if the check fails or
3741 main.ERROR if there is some error in processing the test
3742 """
3743 try:
Jon Hall390696c2015-05-05 17:13:41 -07003744 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003745 rawJson = self.appIDs( jsonFormat=True )
3746 if rawJson:
3747 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003748 else:
Jon Hallc6793552016-01-19 14:18:37 -08003749 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003750 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003751 rawJson = self.apps( jsonFormat=True )
3752 if rawJson:
3753 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003754 else:
Jon Hallc6793552016-01-19 14:18:37 -08003755 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003756 bail = True
3757 if bail:
3758 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003759 result = main.TRUE
3760 for app in apps:
3761 appID = app.get( 'id' )
3762 if appID is None:
3763 main.log.error( "Error parsing app: " + str( app ) )
3764 result = main.FALSE
3765 appName = app.get( 'name' )
3766 if appName is None:
3767 main.log.error( "Error parsing app: " + str( app ) )
3768 result = main.FALSE
3769 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003770 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003771 # main.log.debug( "Comparing " + str( app ) + " to " +
3772 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003773 if not current: # if ids doesn't have this id
3774 result = main.FALSE
3775 main.log.error( "'app-ids' does not have the ID for " +
3776 str( appName ) + " that apps does." )
3777 elif len( current ) > 1:
3778 # there is more than one app with this ID
3779 result = main.FALSE
3780 # We will log this later in the method
3781 elif not current[0][ 'name' ] == appName:
3782 currentName = current[0][ 'name' ]
3783 result = main.FALSE
3784 main.log.error( "'app-ids' has " + str( currentName ) +
3785 " registered under id:" + str( appID ) +
3786 " but 'apps' has " + str( appName ) )
3787 else:
3788 pass # id and name match!
3789 # now make sure that app-ids has no duplicates
3790 idsList = []
3791 namesList = []
3792 for item in ids:
3793 idsList.append( item[ 'id' ] )
3794 namesList.append( item[ 'name' ] )
3795 if len( idsList ) != len( set( idsList ) ) or\
3796 len( namesList ) != len( set( namesList ) ):
3797 main.log.error( "'app-ids' has some duplicate entries: \n"
3798 + json.dumps( ids,
3799 sort_keys=True,
3800 indent=4,
3801 separators=( ',', ': ' ) ) )
3802 result = main.FALSE
3803 return result
Jon Hallc6793552016-01-19 14:18:37 -08003804 except ( TypeError, ValueError ):
3805 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003806 return main.ERROR
3807 except pexpect.EOF:
3808 main.log.error( self.name + ": EOF exception found" )
3809 main.log.error( self.name + ": " + self.handle.before )
3810 main.cleanup()
3811 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003812 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003813 main.log.exception( self.name + ": Uncaught exception!" )
3814 main.cleanup()
3815 main.exit()
3816
Jon Hallfb760a02015-04-13 15:35:03 -07003817 def getCfg( self, component=None, propName=None, short=False,
3818 jsonFormat=True ):
3819 """
3820 Get configuration settings from onos cli
3821 Optional arguments:
3822 component - Optionally only list configurations for a specific
3823 component. If None, all components with configurations
3824 are displayed. Case Sensitive string.
3825 propName - If component is specified, propName option will show
3826 only this specific configuration from that component.
3827 Case Sensitive string.
3828 jsonFormat - Returns output as json. Note that this will override
3829 the short option
3830 short - Short, less verbose, version of configurations.
3831 This is overridden by the json option
3832 returns:
3833 Output from cli as a string or None on error
3834 """
3835 try:
3836 baseStr = "cfg"
3837 cmdStr = " get"
3838 componentStr = ""
3839 if component:
3840 componentStr += " " + component
3841 if propName:
3842 componentStr += " " + propName
3843 if jsonFormat:
3844 baseStr += " -j"
3845 elif short:
3846 baseStr += " -s"
3847 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003848 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003849 assert "Command not found:" not in output, output
3850 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003851 return output
3852 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003853 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003854 return None
3855 except TypeError:
3856 main.log.exception( self.name + ": Object not as expected" )
3857 return None
3858 except pexpect.EOF:
3859 main.log.error( self.name + ": EOF exception found" )
3860 main.log.error( self.name + ": " + self.handle.before )
3861 main.cleanup()
3862 main.exit()
3863 except Exception:
3864 main.log.exception( self.name + ": Uncaught exception!" )
3865 main.cleanup()
3866 main.exit()
3867
3868 def setCfg( self, component, propName, value=None, check=True ):
3869 """
3870 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003871 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003872 component - The case sensitive name of the component whose
3873 property is to be set
3874 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003875 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003876 value - The value to set the property to. If None, will unset the
3877 property and revert it to it's default value(if applicable)
3878 check - Boolean, Check whether the option was successfully set this
3879 only applies when a value is given.
3880 returns:
3881 main.TRUE on success or main.FALSE on failure. If check is False,
3882 will return main.TRUE unless there is an error
3883 """
3884 try:
3885 baseStr = "cfg"
3886 cmdStr = " set " + str( component ) + " " + str( propName )
3887 if value is not None:
3888 cmdStr += " " + str( value )
3889 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003890 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003891 assert "Command not found:" not in output, output
3892 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003893 if value and check:
3894 results = self.getCfg( component=str( component ),
3895 propName=str( propName ),
3896 jsonFormat=True )
3897 # Check if current value is what we just set
3898 try:
3899 jsonOutput = json.loads( results )
3900 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003901 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003902 main.log.exception( "Error parsing cfg output" )
3903 main.log.error( "output:" + repr( results ) )
3904 return main.FALSE
3905 if current == str( value ):
3906 return main.TRUE
3907 return main.FALSE
3908 return main.TRUE
3909 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003910 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003911 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003912 except ( TypeError, ValueError ):
3913 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003914 return main.FALSE
3915 except pexpect.EOF:
3916 main.log.error( self.name + ": EOF exception found" )
3917 main.log.error( self.name + ": " + self.handle.before )
3918 main.cleanup()
3919 main.exit()
3920 except Exception:
3921 main.log.exception( self.name + ": Uncaught exception!" )
3922 main.cleanup()
3923 main.exit()
3924
Jon Hall390696c2015-05-05 17:13:41 -07003925 def setTestAdd( self, setName, values ):
3926 """
3927 CLI command to add elements to a distributed set.
3928 Arguments:
3929 setName - The name of the set to add to.
3930 values - The value(s) to add to the set, space seperated.
3931 Example usages:
3932 setTestAdd( "set1", "a b c" )
3933 setTestAdd( "set2", "1" )
3934 returns:
3935 main.TRUE on success OR
3936 main.FALSE if elements were already in the set OR
3937 main.ERROR on error
3938 """
3939 try:
3940 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3941 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003942 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003943 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003944 try:
3945 # TODO: Maybe make this less hardcoded
3946 # ConsistentMap Exceptions
3947 assert "org.onosproject.store.service" not in output
3948 # Node not leader
3949 assert "java.lang.IllegalStateException" not in output
3950 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003951 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003952 "command: " + str( output ) )
3953 retryTime = 30 # Conservative time, given by Madan
3954 main.log.info( "Waiting " + str( retryTime ) +
3955 "seconds before retrying." )
3956 time.sleep( retryTime ) # Due to change in mastership
3957 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003958 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003959 assert "Error executing command" not in output
3960 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3961 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3962 main.log.info( self.name + ": " + output )
3963 if re.search( positiveMatch, output):
3964 return main.TRUE
3965 elif re.search( negativeMatch, output):
3966 return main.FALSE
3967 else:
3968 main.log.error( self.name + ": setTestAdd did not" +
3969 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003970 main.log.debug( self.name + " actual: " + repr( output ) )
3971 return main.ERROR
3972 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003973 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003974 return main.ERROR
3975 except TypeError:
3976 main.log.exception( self.name + ": Object not as expected" )
3977 return main.ERROR
3978 except pexpect.EOF:
3979 main.log.error( self.name + ": EOF exception found" )
3980 main.log.error( self.name + ": " + self.handle.before )
3981 main.cleanup()
3982 main.exit()
3983 except Exception:
3984 main.log.exception( self.name + ": Uncaught exception!" )
3985 main.cleanup()
3986 main.exit()
3987
3988 def setTestRemove( self, setName, values, clear=False, retain=False ):
3989 """
3990 CLI command to remove elements from a distributed set.
3991 Required arguments:
3992 setName - The name of the set to remove from.
3993 values - The value(s) to remove from the set, space seperated.
3994 Optional arguments:
3995 clear - Clear all elements from the set
3996 retain - Retain only the given values. (intersection of the
3997 original set and the given set)
3998 returns:
3999 main.TRUE on success OR
4000 main.FALSE if the set was not changed OR
4001 main.ERROR on error
4002 """
4003 try:
4004 cmdStr = "set-test-remove "
4005 if clear:
4006 cmdStr += "-c " + str( setName )
4007 elif retain:
4008 cmdStr += "-r " + str( setName ) + " " + str( values )
4009 else:
4010 cmdStr += str( setName ) + " " + str( values )
4011 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004012 try:
Jon Halla495f562016-05-16 18:03:26 -07004013 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004014 # TODO: Maybe make this less hardcoded
4015 # ConsistentMap Exceptions
4016 assert "org.onosproject.store.service" not in output
4017 # Node not leader
4018 assert "java.lang.IllegalStateException" not in output
4019 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004020 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004021 "command: " + str( output ) )
4022 retryTime = 30 # Conservative time, given by Madan
4023 main.log.info( "Waiting " + str( retryTime ) +
4024 "seconds before retrying." )
4025 time.sleep( retryTime ) # Due to change in mastership
4026 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004027 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004028 assert "Command not found:" not in output, output
4029 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004030 main.log.info( self.name + ": " + output )
4031 if clear:
4032 pattern = "Set " + str( setName ) + " cleared"
4033 if re.search( pattern, output ):
4034 return main.TRUE
4035 elif retain:
4036 positivePattern = str( setName ) + " was pruned to contain " +\
4037 "only elements of set \[(.*)\]"
4038 negativePattern = str( setName ) + " was not changed by " +\
4039 "retaining only elements of the set " +\
4040 "\[(.*)\]"
4041 if re.search( positivePattern, output ):
4042 return main.TRUE
4043 elif re.search( negativePattern, output ):
4044 return main.FALSE
4045 else:
4046 positivePattern = "\[(.*)\] was removed from the set " +\
4047 str( setName )
4048 if ( len( values.split() ) == 1 ):
4049 negativePattern = "\[(.*)\] was not in set " +\
4050 str( setName )
4051 else:
4052 negativePattern = "No element of \[(.*)\] was in set " +\
4053 str( setName )
4054 if re.search( positivePattern, output ):
4055 return main.TRUE
4056 elif re.search( negativePattern, output ):
4057 return main.FALSE
4058 main.log.error( self.name + ": setTestRemove did not" +
4059 " match expected output" )
4060 main.log.debug( self.name + " expected: " + pattern )
4061 main.log.debug( self.name + " actual: " + repr( output ) )
4062 return main.ERROR
4063 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004064 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004065 return main.ERROR
4066 except TypeError:
4067 main.log.exception( self.name + ": Object not as expected" )
4068 return main.ERROR
4069 except pexpect.EOF:
4070 main.log.error( self.name + ": EOF exception found" )
4071 main.log.error( self.name + ": " + self.handle.before )
4072 main.cleanup()
4073 main.exit()
4074 except Exception:
4075 main.log.exception( self.name + ": Uncaught exception!" )
4076 main.cleanup()
4077 main.exit()
4078
4079 def setTestGet( self, setName, values="" ):
4080 """
4081 CLI command to get the elements in a distributed set.
4082 Required arguments:
4083 setName - The name of the set to remove from.
4084 Optional arguments:
4085 values - The value(s) to check if in the set, space seperated.
4086 returns:
4087 main.ERROR on error OR
4088 A list of elements in the set if no optional arguments are
4089 supplied OR
4090 A tuple containing the list then:
4091 main.FALSE if the given values are not in the set OR
4092 main.TRUE if the given values are in the set OR
4093 """
4094 try:
4095 values = str( values ).strip()
4096 setName = str( setName ).strip()
4097 length = len( values.split() )
4098 containsCheck = None
4099 # Patterns to match
4100 setPattern = "\[(.*)\]"
4101 pattern = "Items in set " + setName + ":\n" + setPattern
4102 containsTrue = "Set " + setName + " contains the value " + values
4103 containsFalse = "Set " + setName + " did not contain the value " +\
4104 values
4105 containsAllTrue = "Set " + setName + " contains the the subset " +\
4106 setPattern
4107 containsAllFalse = "Set " + setName + " did not contain the the" +\
4108 " subset " + setPattern
4109
4110 cmdStr = "set-test-get "
4111 cmdStr += setName + " " + values
4112 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004113 try:
Jon Halla495f562016-05-16 18:03:26 -07004114 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004115 # TODO: Maybe make this less hardcoded
4116 # ConsistentMap Exceptions
4117 assert "org.onosproject.store.service" not in output
4118 # Node not leader
4119 assert "java.lang.IllegalStateException" not in output
4120 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004121 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004122 "command: " + str( output ) )
4123 retryTime = 30 # Conservative time, given by Madan
4124 main.log.info( "Waiting " + str( retryTime ) +
4125 "seconds before retrying." )
4126 time.sleep( retryTime ) # Due to change in mastership
4127 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004128 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004129 assert "Command not found:" not in output, output
4130 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004131 main.log.info( self.name + ": " + output )
4132
4133 if length == 0:
4134 match = re.search( pattern, output )
4135 else: # if given values
4136 if length == 1: # Contains output
4137 patternTrue = pattern + "\n" + containsTrue
4138 patternFalse = pattern + "\n" + containsFalse
4139 else: # ContainsAll output
4140 patternTrue = pattern + "\n" + containsAllTrue
4141 patternFalse = pattern + "\n" + containsAllFalse
4142 matchTrue = re.search( patternTrue, output )
4143 matchFalse = re.search( patternFalse, output )
4144 if matchTrue:
4145 containsCheck = main.TRUE
4146 match = matchTrue
4147 elif matchFalse:
4148 containsCheck = main.FALSE
4149 match = matchFalse
4150 else:
4151 main.log.error( self.name + " setTestGet did not match " +\
4152 "expected output" )
4153 main.log.debug( self.name + " expected: " + pattern )
4154 main.log.debug( self.name + " actual: " + repr( output ) )
4155 match = None
4156 if match:
4157 setMatch = match.group( 1 )
4158 if setMatch == '':
4159 setList = []
4160 else:
4161 setList = setMatch.split( ", " )
4162 if length > 0:
4163 return ( setList, containsCheck )
4164 else:
4165 return setList
4166 else: # no match
4167 main.log.error( self.name + ": setTestGet did not" +
4168 " match expected output" )
4169 main.log.debug( self.name + " expected: " + pattern )
4170 main.log.debug( self.name + " actual: " + repr( output ) )
4171 return main.ERROR
4172 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004173 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004174 return main.ERROR
4175 except TypeError:
4176 main.log.exception( self.name + ": Object not as expected" )
4177 return main.ERROR
4178 except pexpect.EOF:
4179 main.log.error( self.name + ": EOF exception found" )
4180 main.log.error( self.name + ": " + self.handle.before )
4181 main.cleanup()
4182 main.exit()
4183 except Exception:
4184 main.log.exception( self.name + ": Uncaught exception!" )
4185 main.cleanup()
4186 main.exit()
4187
4188 def setTestSize( self, setName ):
4189 """
4190 CLI command to get the elements in a distributed set.
4191 Required arguments:
4192 setName - The name of the set to remove from.
4193 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004194 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004195 None on error
4196 """
4197 try:
4198 # TODO: Should this check against the number of elements returned
4199 # and then return true/false based on that?
4200 setName = str( setName ).strip()
4201 # Patterns to match
4202 setPattern = "\[(.*)\]"
4203 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4204 setPattern
4205 cmdStr = "set-test-get -s "
4206 cmdStr += setName
4207 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004208 try:
Jon Halla495f562016-05-16 18:03:26 -07004209 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004210 # TODO: Maybe make this less hardcoded
4211 # ConsistentMap Exceptions
4212 assert "org.onosproject.store.service" not in output
4213 # Node not leader
4214 assert "java.lang.IllegalStateException" not in output
4215 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004216 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004217 "command: " + str( output ) )
4218 retryTime = 30 # Conservative time, given by Madan
4219 main.log.info( "Waiting " + str( retryTime ) +
4220 "seconds before retrying." )
4221 time.sleep( retryTime ) # Due to change in mastership
4222 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004223 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004224 assert "Command not found:" not in output, output
4225 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004226 main.log.info( self.name + ": " + output )
4227 match = re.search( pattern, output )
4228 if match:
4229 setSize = int( match.group( 1 ) )
4230 setMatch = match.group( 2 )
4231 if len( setMatch.split() ) == setSize:
4232 main.log.info( "The size returned by " + self.name +
4233 " matches the number of elements in " +
4234 "the returned set" )
4235 else:
4236 main.log.error( "The size returned by " + self.name +
4237 " does not match the number of " +
4238 "elements in the returned set." )
4239 return setSize
4240 else: # no match
4241 main.log.error( self.name + ": setTestGet did not" +
4242 " match expected output" )
4243 main.log.debug( self.name + " expected: " + pattern )
4244 main.log.debug( self.name + " actual: " + repr( output ) )
4245 return None
4246 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004247 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004248 return None
Jon Hall390696c2015-05-05 17:13:41 -07004249 except TypeError:
4250 main.log.exception( self.name + ": Object not as expected" )
4251 return None
4252 except pexpect.EOF:
4253 main.log.error( self.name + ": EOF exception found" )
4254 main.log.error( self.name + ": " + self.handle.before )
4255 main.cleanup()
4256 main.exit()
4257 except Exception:
4258 main.log.exception( self.name + ": Uncaught exception!" )
4259 main.cleanup()
4260 main.exit()
4261
Jon Hall80daded2015-05-27 16:07:00 -07004262 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004263 """
4264 Command to list the various counters in the system.
4265 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004266 if jsonFormat, a string of the json object returned by the cli
4267 command
4268 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004269 None on error
4270 """
Jon Hall390696c2015-05-05 17:13:41 -07004271 try:
4272 counters = {}
4273 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004274 if jsonFormat:
4275 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004276 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004277 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004278 assert "Command not found:" not in output, output
4279 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004280 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004281 return output
Jon Hall390696c2015-05-05 17:13:41 -07004282 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004283 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004284 return None
Jon Hall390696c2015-05-05 17:13:41 -07004285 except TypeError:
4286 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004287 return None
Jon Hall390696c2015-05-05 17:13:41 -07004288 except pexpect.EOF:
4289 main.log.error( self.name + ": EOF exception found" )
4290 main.log.error( self.name + ": " + self.handle.before )
4291 main.cleanup()
4292 main.exit()
4293 except Exception:
4294 main.log.exception( self.name + ": Uncaught exception!" )
4295 main.cleanup()
4296 main.exit()
4297
Jon Hall935db192016-04-19 00:22:04 -07004298 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004299 """
Jon Halle1a3b752015-07-22 13:02:46 -07004300 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004301 Required arguments:
4302 counter - The name of the counter to increment.
4303 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004304 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004305 returns:
4306 integer value of the counter or
4307 None on Error
4308 """
4309 try:
4310 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004311 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004312 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004313 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004314 if delta != 1:
4315 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004316 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004317 try:
Jon Halla495f562016-05-16 18:03:26 -07004318 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004319 # TODO: Maybe make this less hardcoded
4320 # ConsistentMap Exceptions
4321 assert "org.onosproject.store.service" not in output
4322 # Node not leader
4323 assert "java.lang.IllegalStateException" not in output
4324 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004325 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004326 "command: " + str( output ) )
4327 retryTime = 30 # Conservative time, given by Madan
4328 main.log.info( "Waiting " + str( retryTime ) +
4329 "seconds before retrying." )
4330 time.sleep( retryTime ) # Due to change in mastership
4331 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004332 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004333 assert "Command not found:" not in output, output
4334 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004335 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004336 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004337 match = re.search( pattern, output )
4338 if match:
4339 return int( match.group( 1 ) )
4340 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004341 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004342 " match expected output." )
4343 main.log.debug( self.name + " expected: " + pattern )
4344 main.log.debug( self.name + " actual: " + repr( output ) )
4345 return None
4346 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004347 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004348 return None
4349 except TypeError:
4350 main.log.exception( self.name + ": Object not as expected" )
4351 return None
4352 except pexpect.EOF:
4353 main.log.error( self.name + ": EOF exception found" )
4354 main.log.error( self.name + ": " + self.handle.before )
4355 main.cleanup()
4356 main.exit()
4357 except Exception:
4358 main.log.exception( self.name + ": Uncaught exception!" )
4359 main.cleanup()
4360 main.exit()
4361
Jon Hall935db192016-04-19 00:22:04 -07004362 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004363 """
4364 CLI command to get a distributed counter then add a delta to it.
4365 Required arguments:
4366 counter - The name of the counter to increment.
4367 Optional arguments:
4368 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004369 returns:
4370 integer value of the counter or
4371 None on Error
4372 """
4373 try:
4374 counter = str( counter )
4375 delta = int( delta )
4376 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004377 cmdStr += counter
4378 if delta != 1:
4379 cmdStr += " " + str( delta )
4380 output = self.sendline( cmdStr )
4381 try:
Jon Halla495f562016-05-16 18:03:26 -07004382 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004383 # TODO: Maybe make this less hardcoded
4384 # ConsistentMap Exceptions
4385 assert "org.onosproject.store.service" not in output
4386 # Node not leader
4387 assert "java.lang.IllegalStateException" not in output
4388 except AssertionError:
4389 main.log.error( "Error in processing '" + cmdStr + "' " +
4390 "command: " + str( output ) )
4391 retryTime = 30 # Conservative time, given by Madan
4392 main.log.info( "Waiting " + str( retryTime ) +
4393 "seconds before retrying." )
4394 time.sleep( retryTime ) # Due to change in mastership
4395 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004396 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004397 assert "Command not found:" not in output, output
4398 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004399 main.log.info( self.name + ": " + output )
4400 pattern = counter + " was updated to (-?\d+)"
4401 match = re.search( pattern, output )
4402 if match:
4403 return int( match.group( 1 ) )
4404 else:
4405 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4406 " match expected output." )
4407 main.log.debug( self.name + " expected: " + pattern )
4408 main.log.debug( self.name + " actual: " + repr( output ) )
4409 return None
4410 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004411 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004412 return None
4413 except TypeError:
4414 main.log.exception( self.name + ": Object not as expected" )
4415 return None
4416 except pexpect.EOF:
4417 main.log.error( self.name + ": EOF exception found" )
4418 main.log.error( self.name + ": " + self.handle.before )
4419 main.cleanup()
4420 main.exit()
4421 except Exception:
4422 main.log.exception( self.name + ": Uncaught exception!" )
4423 main.cleanup()
4424 main.exit()
4425
YPZhangfebf7302016-05-24 16:45:56 -07004426 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004427 """
4428 Description: Execute summary command in onos
4429 Returns: json object ( summary -j ), returns main.FALSE if there is
4430 no output
4431
4432 """
4433 try:
4434 cmdStr = "summary"
4435 if jsonFormat:
4436 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004437 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004438 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004439 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004440 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004441 if not handle:
4442 main.log.error( self.name + ": There is no output in " +
4443 "summary command" )
4444 return main.FALSE
4445 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004446 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004447 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004448 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004449 except TypeError:
4450 main.log.exception( self.name + ": Object not as expected" )
4451 return None
4452 except pexpect.EOF:
4453 main.log.error( self.name + ": EOF exception found" )
4454 main.log.error( self.name + ": " + self.handle.before )
4455 main.cleanup()
4456 main.exit()
4457 except Exception:
4458 main.log.exception( self.name + ": Uncaught exception!" )
4459 main.cleanup()
4460 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004461
Jon Hall935db192016-04-19 00:22:04 -07004462 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004463 """
4464 CLI command to get the value of a key in a consistent map using
4465 transactions. This a test function and can only get keys from the
4466 test map hard coded into the cli command
4467 Required arguments:
4468 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004469 returns:
4470 The string value of the key or
4471 None on Error
4472 """
4473 try:
4474 keyName = str( keyName )
4475 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004476 cmdStr += keyName
4477 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004478 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004479 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004480 try:
4481 # TODO: Maybe make this less hardcoded
4482 # ConsistentMap Exceptions
4483 assert "org.onosproject.store.service" not in output
4484 # Node not leader
4485 assert "java.lang.IllegalStateException" not in output
4486 except AssertionError:
4487 main.log.error( "Error in processing '" + cmdStr + "' " +
4488 "command: " + str( output ) )
4489 return None
4490 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4491 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004492 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004493 return None
4494 else:
4495 match = re.search( pattern, output )
4496 if match:
4497 return match.groupdict()[ 'value' ]
4498 else:
4499 main.log.error( self.name + ": transactionlMapGet did not" +
4500 " match expected output." )
4501 main.log.debug( self.name + " expected: " + pattern )
4502 main.log.debug( self.name + " actual: " + repr( output ) )
4503 return None
Jon Hallc6793552016-01-19 14:18:37 -08004504 except AssertionError:
4505 main.log.exception( "" )
4506 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004507 except TypeError:
4508 main.log.exception( self.name + ": Object not as expected" )
4509 return None
4510 except pexpect.EOF:
4511 main.log.error( self.name + ": EOF exception found" )
4512 main.log.error( self.name + ": " + self.handle.before )
4513 main.cleanup()
4514 main.exit()
4515 except Exception:
4516 main.log.exception( self.name + ": Uncaught exception!" )
4517 main.cleanup()
4518 main.exit()
4519
Jon Hall935db192016-04-19 00:22:04 -07004520 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004521 """
4522 CLI command to put a value into 'numKeys' number of keys in a
4523 consistent map using transactions. This a test function and can only
4524 put into keys named 'Key#' of the test map hard coded into the cli command
4525 Required arguments:
4526 numKeys - Number of keys to add the value to
4527 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004528 returns:
4529 A dictionary whose keys are the name of the keys put into the map
4530 and the values of the keys are dictionaries whose key-values are
4531 'value': value put into map and optionaly
4532 'oldValue': Previous value in the key or
4533 None on Error
4534
4535 Example output
4536 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4537 'Key2': {'value': 'Testing'} }
4538 """
4539 try:
4540 numKeys = str( numKeys )
4541 value = str( value )
4542 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004543 cmdStr += numKeys + " " + value
4544 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004545 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004546 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004547 try:
4548 # TODO: Maybe make this less hardcoded
4549 # ConsistentMap Exceptions
4550 assert "org.onosproject.store.service" not in output
4551 # Node not leader
4552 assert "java.lang.IllegalStateException" not in output
4553 except AssertionError:
4554 main.log.error( "Error in processing '" + cmdStr + "' " +
4555 "command: " + str( output ) )
4556 return None
4557 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4558 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4559 results = {}
4560 for line in output.splitlines():
4561 new = re.search( newPattern, line )
4562 updated = re.search( updatedPattern, line )
4563 if new:
4564 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4565 elif updated:
4566 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004567 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004568 else:
4569 main.log.error( self.name + ": transactionlMapGet did not" +
4570 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004571 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4572 newPattern,
4573 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004574 main.log.debug( self.name + " actual: " + repr( output ) )
4575 return results
Jon Hallc6793552016-01-19 14:18:37 -08004576 except AssertionError:
4577 main.log.exception( "" )
4578 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004579 except TypeError:
4580 main.log.exception( self.name + ": Object not as expected" )
4581 return None
4582 except pexpect.EOF:
4583 main.log.error( self.name + ": EOF exception found" )
4584 main.log.error( self.name + ": " + self.handle.before )
4585 main.cleanup()
4586 main.exit()
4587 except Exception:
4588 main.log.exception( self.name + ": Uncaught exception!" )
4589 main.cleanup()
4590 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004591
acsmarsdaea66c2015-09-03 11:44:06 -07004592 def maps( self, jsonFormat=True ):
4593 """
4594 Description: Returns result of onos:maps
4595 Optional:
4596 * jsonFormat: enable json formatting of output
4597 """
4598 try:
4599 cmdStr = "maps"
4600 if jsonFormat:
4601 cmdStr += " -j"
4602 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004603 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004604 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004605 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004606 except AssertionError:
4607 main.log.exception( "" )
4608 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004609 except TypeError:
4610 main.log.exception( self.name + ": Object not as expected" )
4611 return None
4612 except pexpect.EOF:
4613 main.log.error( self.name + ": EOF exception found" )
4614 main.log.error( self.name + ": " + self.handle.before )
4615 main.cleanup()
4616 main.exit()
4617 except Exception:
4618 main.log.exception( self.name + ": Uncaught exception!" )
4619 main.cleanup()
4620 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004621
4622 def getSwController( self, uri, jsonFormat=True ):
4623 """
4624 Descrition: Gets the controller information from the device
4625 """
4626 try:
4627 cmd = "device-controllers "
4628 if jsonFormat:
4629 cmd += "-j "
4630 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004631 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004632 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004633 return response
Jon Hallc6793552016-01-19 14:18:37 -08004634 except AssertionError:
4635 main.log.exception( "" )
4636 return None
GlennRC050596c2015-11-18 17:06:41 -08004637 except TypeError:
4638 main.log.exception( self.name + ": Object not as expected" )
4639 return None
4640 except pexpect.EOF:
4641 main.log.error( self.name + ": EOF exception found" )
4642 main.log.error( self.name + ": " + self.handle.before )
4643 main.cleanup()
4644 main.exit()
4645 except Exception:
4646 main.log.exception( self.name + ": Uncaught exception!" )
4647 main.cleanup()
4648 main.exit()
4649
4650 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4651 """
4652 Descrition: sets the controller(s) for the specified device
4653
4654 Parameters:
4655 Required: uri - String: The uri of the device(switch).
4656 ip - String or List: The ip address of the controller.
4657 This parameter can be formed in a couple of different ways.
4658 VALID:
4659 10.0.0.1 - just the ip address
4660 tcp:10.0.0.1 - the protocol and the ip address
4661 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4662 so that you can add controllers with different
4663 protocols and ports
4664 INVALID:
4665 10.0.0.1:6653 - this is not supported by ONOS
4666
4667 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4668 port - The port number.
4669 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4670
4671 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4672 """
4673 try:
4674 cmd = "device-setcontrollers"
4675
4676 if jsonFormat:
4677 cmd += " -j"
4678 cmd += " " + uri
4679 if isinstance( ip, str ):
4680 ip = [ip]
4681 for item in ip:
4682 if ":" in item:
4683 sitem = item.split( ":" )
4684 if len(sitem) == 3:
4685 cmd += " " + item
4686 elif "." in sitem[1]:
4687 cmd += " {}:{}".format(item, port)
4688 else:
4689 main.log.error( "Malformed entry: " + item )
4690 raise TypeError
4691 else:
4692 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004693 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004694 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004695 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004696 if "Error" in response:
4697 main.log.error( response )
4698 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004699 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004700 except AssertionError:
4701 main.log.exception( "" )
4702 return None
GlennRC050596c2015-11-18 17:06:41 -08004703 except TypeError:
4704 main.log.exception( self.name + ": Object not as expected" )
4705 return main.FALSE
4706 except pexpect.EOF:
4707 main.log.error( self.name + ": EOF exception found" )
4708 main.log.error( self.name + ": " + self.handle.before )
4709 main.cleanup()
4710 main.exit()
4711 except Exception:
4712 main.log.exception( self.name + ": Uncaught exception!" )
4713 main.cleanup()
4714 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004715
4716 def removeDevice( self, device ):
4717 '''
4718 Description:
4719 Remove a device from ONOS by passing the uri of the device(s).
4720 Parameters:
4721 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4722 Returns:
4723 Returns main.FALSE if an exception is thrown or an error is present
4724 in the response. Otherwise, returns main.TRUE.
4725 NOTE:
4726 If a host cannot be removed, then this function will return main.FALSE
4727 '''
4728 try:
4729 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004730 deviceStr = device
4731 device = []
4732 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004733
4734 for d in device:
4735 time.sleep( 1 )
4736 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004737 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004738 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004739 if "Error" in response:
4740 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4741 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004742 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004743 except AssertionError:
4744 main.log.exception( "" )
4745 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004746 except TypeError:
4747 main.log.exception( self.name + ": Object not as expected" )
4748 return main.FALSE
4749 except pexpect.EOF:
4750 main.log.error( self.name + ": EOF exception found" )
4751 main.log.error( self.name + ": " + self.handle.before )
4752 main.cleanup()
4753 main.exit()
4754 except Exception:
4755 main.log.exception( self.name + ": Uncaught exception!" )
4756 main.cleanup()
4757 main.exit()
4758
4759 def removeHost( self, host ):
4760 '''
4761 Description:
4762 Remove a host from ONOS by passing the id of the host(s)
4763 Parameters:
4764 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4765 Returns:
4766 Returns main.FALSE if an exception is thrown or an error is present
4767 in the response. Otherwise, returns main.TRUE.
4768 NOTE:
4769 If a host cannot be removed, then this function will return main.FALSE
4770 '''
4771 try:
4772 if type( host ) is str:
4773 host = list( host )
4774
4775 for h in host:
4776 time.sleep( 1 )
4777 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004778 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004779 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004780 if "Error" in response:
4781 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4782 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004784 except AssertionError:
4785 main.log.exception( "" )
4786 return None
GlennRC20fc6522015-12-23 23:26:57 -08004787 except TypeError:
4788 main.log.exception( self.name + ": Object not as expected" )
4789 return main.FALSE
4790 except pexpect.EOF:
4791 main.log.error( self.name + ": EOF exception found" )
4792 main.log.error( self.name + ": " + self.handle.before )
4793 main.cleanup()
4794 main.exit()
4795 except Exception:
4796 main.log.exception( self.name + ": Uncaught exception!" )
4797 main.cleanup()
4798 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004799
YPZhangfebf7302016-05-24 16:45:56 -07004800 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004801 '''
4802 Description:
4803 Bring link down or up in the null-provider.
4804 params:
4805 begin - (string) One end of a device or switch.
4806 end - (string) the other end of the device or switch
4807 returns:
4808 main.TRUE if no exceptions were thrown and no Errors are
4809 present in the resoponse. Otherwise, returns main.FALSE
4810 '''
4811 try:
Jon Hallc6793552016-01-19 14:18:37 -08004812 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004813 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004814 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004815 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004816 if "Error" in response or "Failure" in response:
4817 main.log.error( response )
4818 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004819 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004820 except AssertionError:
4821 main.log.exception( "" )
4822 return None
GlennRCed771242016-01-13 17:02:47 -08004823 except TypeError:
4824 main.log.exception( self.name + ": Object not as expected" )
4825 return main.FALSE
4826 except pexpect.EOF:
4827 main.log.error( self.name + ": EOF exception found" )
4828 main.log.error( self.name + ": " + self.handle.before )
4829 main.cleanup()
4830 main.exit()
4831 except Exception:
4832 main.log.exception( self.name + ": Uncaught exception!" )
4833 main.cleanup()
4834 main.exit()
4835
Flavio Castro82ee2f62016-06-07 15:04:12 -07004836 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4837 '''
4838 Description:
4839 Changes the state of port in an OF switch by means of the
4840 PORTSTATUS OF messages.
4841 params:
4842 dpid - (string) Datapath ID of the device
4843 port - (string) target port in the device
4844 state - (string) target state (enable or disabled)
4845 returns:
4846 main.TRUE if no exceptions were thrown and no Errors are
4847 present in the resoponse. Otherwise, returns main.FALSE
4848 '''
4849 try:
4850 cmd = "portstate {} {} {}".format( dpid, port, state )
4851 response = self.sendline( cmd, showResponse=True )
4852 assert response is not None, "Error in sendline"
4853 assert "Command not found:" not in response, response
4854 if "Error" in response or "Failure" in response:
4855 main.log.error( response )
4856 return main.FALSE
4857 return main.TRUE
4858 except AssertionError:
4859 main.log.exception( "" )
4860 return None
4861 except TypeError:
4862 main.log.exception( self.name + ": Object not as expected" )
4863 return main.FALSE
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()
4873
4874 def logSet( self, level="INFO", app="org.onosproject" ):
4875 """
4876 Set the logging level to lvl for a specific app
4877 returns main.TRUE on success
4878 returns main.FALSE if Error occurred
4879 if noExit is True, TestON will not exit, but clean up
4880 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4881 Level defaults to INFO
4882 """
4883 try:
4884 self.handle.sendline( "log:set %s %s" %( level, app ) )
4885 self.handle.expect( "onos>" )
4886
4887 response = self.handle.before
4888 if re.search( "Error", response ):
4889 return main.FALSE
4890 return main.TRUE
4891 except pexpect.TIMEOUT:
4892 main.log.exception( self.name + ": TIMEOUT exception found" )
4893 main.cleanup()
4894 main.exit()
4895 except pexpect.EOF:
4896 main.log.error( self.name + ": EOF exception found" )
4897 main.log.error( self.name + ": " + self.handle.before )
4898 main.cleanup()
4899 main.exit()
4900 except Exception:
4901 main.log.exception( self.name + ": Uncaught exception!" )
4902 main.cleanup()
4903 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004904
4905 def getGraphDict( self, timeout=60, includeHost=False ):
4906 """
4907 Return a dictionary which describes the latest network topology data as a
4908 graph.
4909 An example of the dictionary:
4910 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4911 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4912 Each vertex should at least have an 'edges' attribute which describes the
4913 adjacency information. The value of 'edges' attribute is also represented by
4914 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4915 list of attributes.
4916 An example of the edges dictionary:
4917 'edges': { vertex2: { 'port': ..., 'weight': ... },
4918 vertex3: { 'port': ..., 'weight': ... } }
4919 If includeHost == True, all hosts (and host-switch links) will be included
4920 in topology data.
4921 """
4922 graphDict = {}
4923 try:
4924 links = self.links()
4925 links = json.loads( links )
4926 devices = self.devices()
4927 devices = json.loads( devices )
4928 idToDevice = {}
4929 for device in devices:
4930 idToDevice[ device[ 'id' ] ] = device
4931 if includeHost:
4932 hosts = self.hosts()
4933 # FIXME: support 'includeHost' argument
4934 for link in links:
4935 nodeA = link[ 'src' ][ 'device' ]
4936 nodeB = link[ 'dst' ][ 'device' ]
4937 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4938 if not nodeA in graphDict.keys():
4939 graphDict[ nodeA ] = { 'edges':{},
4940 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4941 'type':idToDevice[ nodeA ][ 'type' ],
4942 'available':idToDevice[ nodeA ][ 'available' ],
4943 'role':idToDevice[ nodeA ][ 'role' ],
4944 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4945 'hw':idToDevice[ nodeA ][ 'hw' ],
4946 'sw':idToDevice[ nodeA ][ 'sw' ],
4947 'serial':idToDevice[ nodeA ][ 'serial' ],
4948 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4949 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4950 else:
4951 # Assert nodeB is not connected to any current links of nodeA
4952 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4953 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4954 'type':link[ 'type' ],
4955 'state':link[ 'state' ] }
4956 return graphDict
4957 except ( TypeError, ValueError ):
4958 main.log.exception( self.name + ": Object not as expected" )
4959 return None
4960 except KeyError:
4961 main.log.exception( self.name + ": KeyError exception found" )
4962 return None
4963 except AssertionError:
4964 main.log.exception( self.name + ": AssertionError exception found" )
4965 return None
4966 except pexpect.EOF:
4967 main.log.error( self.name + ": EOF exception found" )
4968 main.log.error( self.name + ": " + self.handle.before )
4969 return None
4970 except Exception:
4971 main.log.exception( self.name + ": Uncaught exception!" )
4972 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004973
4974 def getIntentPerfSummary( self ):
4975 '''
4976 Send command to check intent-perf summary
4977 Returns: dictionary for intent-perf summary
4978 if something wrong, function will return None
4979 '''
4980 cmd = "intent-perf -s"
4981 respDic = {}
4982 resp = self.sendline( cmd )
4983 try:
4984 # Generate the dictionary to return
4985 for l in resp.split( "\n" ):
4986 # Delete any white space in line
4987 temp = re.sub( r'\s+', '', l )
4988 temp = temp.split( ":" )
4989 respDic[ temp[0] ] = temp[ 1 ]
4990
4991 except (TypeError, ValueError):
4992 main.log.exception( self.name + ": Object not as expected" )
4993 return None
4994 except KeyError:
4995 main.log.exception( self.name + ": KeyError exception found" )
4996 return None
4997 except AssertionError:
4998 main.log.exception( self.name + ": AssertionError exception found" )
4999 return None
5000 except pexpect.EOF:
5001 main.log.error( self.name + ": EOF exception found" )
5002 main.log.error( self.name + ": " + self.handle.before )
5003 return None
5004 except Exception:
5005 main.log.exception( self.name + ": Uncaught exception!" )
5006 return None
5007 return respDic
5008
chengchiyu08303a02016-09-08 17:40:26 -07005009 def logSearch( self, searchTerm, mode='all' ):
5010 """
5011 Searches the latest ONOS log file for the given search term and
5012 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005013
chengchiyu08303a02016-09-08 17:40:26 -07005014 Arguments:
5015 searchTerm - A string to grep for in the ONOS log.
5016 mode:
5017 all: return all the strings that contain the search term
5018 last: return the last string that contains the search term
5019 first: return the first string that contains the search term
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005020 num: return the number that the searchTerm appears in the log
chengchiyu08303a02016-09-08 17:40:26 -07005021 """
5022 try:
5023 assert type( searchTerm ) is str
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005024 cmd = "cat /opt/onos/log/karaf.log | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005025 if mode == 'last':
5026 cmd = cmd + " | tail -n 1"
5027 if mode == 'first':
5028 cmd = cmd + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005029 if mode == 'num':
5030 cmd = "cat /opt/onos/log/karaf.log | grep -c \'" + searchTerm + "\'"
5031 num = self.sendline( cmd )
5032 return num
chengchiyu08303a02016-09-08 17:40:26 -07005033 before = self.sendline( cmd )
5034 before = before.splitlines()
5035 # make sure the returned list only contains the search term
5036 returnLines = [line for line in before if searchTerm in line]
5037 return returnLines
5038 except AssertionError:
5039 main.log.error( self.name + " searchTerm is not string type" )
5040 return None
5041 except pexpect.EOF:
5042 main.log.error( self.name + ": EOF exception found" )
5043 main.log.error( self.name + ": " + self.handle.before )
5044 main.cleanup()
5045 main.exit()
5046 except pexpect.TIMEOUT:
5047 main.log.error( self.name + ": TIMEOUT exception found" )
5048 main.log.error( self.name + ": " + self.handle.before )
5049 main.cleanup()
5050 main.exit()
5051 except Exception:
5052 main.log.exception( self.name + ": Uncaught exception!" )
5053 main.cleanup()
5054 main.exit()