blob: 6c3e7d77de704bfd148b882873d963988f4e8a5c [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
YPZhangebf9eb52016-05-12 15:20:24 -0700449 if noExit is True, TestON will not exit, but clean up
450
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." )
468 main.cleanup()
469 main.exit()
470 else:
471 main.cleanup()
472 main.exit()
473 if i == 2:
474 self.handle.sendline( "" )
475 self.handle.expect( "onos>" )
476
Jon Hall14a03b52016-05-11 12:07:30 -0700477 if debug:
478 # NOTE: This adds and average of .4 seconds per call
479 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700480 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800482 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800483 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800484 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800485 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
486 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700487 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700488 main.log.debug( self.name + ": Raw output" )
489 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490
491 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800493 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700494 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700495 main.log.debug( self.name + ": ansiEscape output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
kelvin-onlabfb521662015-02-27 09:52:40 -0800498 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800499 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700501 main.log.debug( self.name + ": Removed extra returns " +
502 "from output" )
503 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700504
505 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800506 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700508 main.log.debug( self.name + ": parsed and stripped output" )
509 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700510
Jon Hall63604932015-02-26 17:09:50 -0800511 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700512 output = response.split( cmdStr.strip(), 1 )
513 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700514 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800517 output = output[1].strip()
518 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800519 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800520 return output
GlennRCed771242016-01-13 17:02:47 -0800521 except pexpect.TIMEOUT:
522 main.log.error( self.name + ":ONOS timeout" )
523 if debug:
524 main.log.debug( self.handle.before )
525 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700526 except IndexError:
527 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700528 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700529 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800530 except TypeError:
531 main.log.exception( self.name + ": Object not as expected" )
532 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800534 main.log.error( self.name + ": EOF exception found" )
535 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700536 if noExit:
537 main.cleanup()
538 return None
539 else:
540 main.cleanup()
541 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800542 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800543 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700544 if noExit:
545 main.cleanup()
546 return None
547 else:
548 main.cleanup()
549 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400550
kelvin8ec71442015-01-15 16:57:00 -0800551 # IMPORTANT NOTE:
552 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800553 # the cli command changing 'a:b' with 'aB'.
554 # Ex ) onos:topology > onosTopology
555 # onos:links > onosLinks
556 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800557
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400560 Adds a new cluster node by ID and address information.
561 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 * nodeId
563 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400564 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800566 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400567 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 cmdStr = "add-node " + str( nodeId ) + " " +\
569 str( ONOSIp ) + " " + str( tcpPort )
570 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700571 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800572 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800573 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800574 main.log.error( "Error in adding node" )
575 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800576 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400577 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800580 except AssertionError:
581 main.log.exception( "" )
582 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800583 except TypeError:
584 main.log.exception( self.name + ": Object not as expected" )
585 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800587 main.log.error( self.name + ": EOF exception found" )
588 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400589 main.cleanup()
590 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800591 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800592 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400593 main.cleanup()
594 main.exit()
595
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800597 """
andrewonlab86dc3082014-10-13 18:18:38 -0400598 Removes a cluster by ID
599 Issues command: 'remove-node [<node-id>]'
600 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800602 """
andrewonlab86dc3082014-10-13 18:18:38 -0400603 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400604
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700606 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700607 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800608 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700609 if re.search( "Error", handle ):
610 main.log.error( "Error in removing node" )
611 main.log.error( handle )
612 return main.FALSE
613 else:
614 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800615 except AssertionError:
616 main.log.exception( "" )
617 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800618 except TypeError:
619 main.log.exception( self.name + ": Object not as expected" )
620 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400621 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800622 main.log.error( self.name + ": EOF exception found" )
623 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400624 main.cleanup()
625 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800626 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800627 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400628 main.cleanup()
629 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400630
Jon Hall61282e32015-03-19 11:34:11 -0700631 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800632 """
andrewonlab7c211572014-10-15 16:45:20 -0400633 List the nodes currently visible
634 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700635 Optional argument:
636 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800637 """
andrewonlab7c211572014-10-15 16:45:20 -0400638 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700639 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700640 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700641 cmdStr += " -j"
642 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700643 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800644 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700645 return output
Jon Hallc6793552016-01-19 14:18:37 -0800646 except AssertionError:
647 main.log.exception( "" )
648 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800649 except TypeError:
650 main.log.exception( self.name + ": Object not as expected" )
651 return None
andrewonlab7c211572014-10-15 16:45:20 -0400652 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800653 main.log.error( self.name + ": EOF exception found" )
654 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400655 main.cleanup()
656 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800658 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400659 main.cleanup()
660 main.exit()
661
kelvin8ec71442015-01-15 16:57:00 -0800662 def topology( self ):
663 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700664 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700665 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700666 Return:
667 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800668 """
andrewonlab95ce8322014-10-13 14:12:04 -0400669 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700670 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800672 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700673 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400674 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800675 except AssertionError:
676 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800677 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400684 main.cleanup()
685 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800686 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800687 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400688 main.cleanup()
689 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800690
jenkins7ead5a82015-03-13 10:28:21 -0700691 def deviceRemove( self, deviceId ):
692 """
693 Removes particular device from storage
694
695 TODO: refactor this function
696 """
697 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700698 cmdStr = "device-remove " + str( deviceId )
699 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800700 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700701 if re.search( "Error", handle ):
702 main.log.error( "Error in removing device" )
703 main.log.error( handle )
704 return main.FALSE
705 else:
706 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800707 except AssertionError:
708 main.log.exception( "" )
709 return None
jenkins7ead5a82015-03-13 10:28:21 -0700710 except TypeError:
711 main.log.exception( self.name + ": Object not as expected" )
712 return None
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
716 main.cleanup()
717 main.exit()
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
720 main.cleanup()
721 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700722
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800724 """
Jon Hall7b02d952014-10-17 20:14:54 -0400725 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400726 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800728 """
andrewonlab86dc3082014-10-13 18:18:38 -0400729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 cmdStr += " -j"
733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800736 except AssertionError:
737 main.log.exception( "" )
738 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800739 except TypeError:
740 main.log.exception( self.name + ": Object not as expected" )
741 return None
andrewonlab7c211572014-10-15 16:45:20 -0400742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800743 main.log.error( self.name + ": EOF exception found" )
744 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400745 main.cleanup()
746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800748 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800754 This balances the devices across all controllers
755 by issuing command: 'onos> onos:balance-masters'
756 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800758 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800759 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700760 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800761 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700762 if re.search( "Error", handle ):
763 main.log.error( "Error in balancing masters" )
764 main.log.error( handle )
765 return main.FALSE
766 else:
767 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800768 except AssertionError:
769 main.log.exception( "" )
770 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800771 except TypeError:
772 main.log.exception( self.name + ": Object not as expected" )
773 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800774 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800775 main.log.error( self.name + ": EOF exception found" )
776 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800777 main.cleanup()
778 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800779 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800780 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800781 main.cleanup()
782 main.exit()
783
Jon Hallc6793552016-01-19 14:18:37 -0800784 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700785 """
786 Returns the output of the masters command.
787 Optional argument:
788 * jsonFormat - boolean indicating if you want output in json
789 """
790 try:
791 cmdStr = "onos:masters"
792 if jsonFormat:
793 cmdStr += " -j"
794 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700795 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800796 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700797 return output
Jon Hallc6793552016-01-19 14:18:37 -0800798 except AssertionError:
799 main.log.exception( "" )
800 return None
acsmars24950022015-07-30 18:00:43 -0700801 except TypeError:
802 main.log.exception( self.name + ": Object not as expected" )
803 return None
804 except pexpect.EOF:
805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
807 main.cleanup()
808 main.exit()
809 except Exception:
810 main.log.exception( self.name + ": Uncaught exception!" )
811 main.cleanup()
812 main.exit()
813
Jon Hallc6793552016-01-19 14:18:37 -0800814 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700815 """
816 Uses the master command to check that the devices' leadership
817 is evenly divided
818
819 Dependencies: checkMasters() and summary()
820
Jon Hall6509dbf2016-06-21 17:01:17 -0700821 Returns main.TRUE if the devices are balanced
822 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700823 Exits on Exception
824 Returns None on TypeError
825 """
826 try:
Jon Hallc6793552016-01-19 14:18:37 -0800827 summaryOutput = self.summary()
828 totalDevices = json.loads( summaryOutput )[ "devices" ]
829 except ( TypeError, ValueError ):
830 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
831 return None
832 try:
acsmars24950022015-07-30 18:00:43 -0700833 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800834 mastersOutput = self.checkMasters()
835 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700836 first = masters[ 0 ][ "size" ]
837 for master in masters:
838 totalOwnedDevices += master[ "size" ]
839 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
840 main.log.error( "Mastership not balanced" )
841 main.log.info( "\n" + self.checkMasters( False ) )
842 return main.FALSE
843 main.log.info( "Mastership balanced between " \
844 + str( len(masters) ) + " masters" )
845 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800846 except ( TypeError, ValueError ):
847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700848 return None
849 except pexpect.EOF:
850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
852 main.cleanup()
853 main.exit()
854 except Exception:
855 main.log.exception( self.name + ": Uncaught exception!" )
856 main.cleanup()
857 main.exit()
858
YPZhangfebf7302016-05-24 16:45:56 -0700859 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Halle8217482014-10-17 13:49:14 -0400861 Lists all core links
862 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800864 """
Jon Halle8217482014-10-17 13:49:14 -0400865 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700869 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800870 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700871 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800872 except AssertionError:
873 main.log.exception( "" )
874 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
Jon Halle8217482014-10-17 13:49:14 -0400878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
Jon Halle8217482014-10-17 13:49:14 -0400890 Lists all ports
891 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800893 """
Jon Halle8217482014-10-17 13:49:14 -0400894 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700897 cmdStr += " -j"
898 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800899 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800901 except AssertionError:
902 main.log.exception( "" )
903 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800904 except TypeError:
905 main.log.exception( self.name + ": Object not as expected" )
906 return None
Jon Halle8217482014-10-17 13:49:14 -0400907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400910 main.cleanup()
911 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800912 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800913 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400914 main.cleanup()
915 main.exit()
916
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800918 """
Jon Hall983a1702014-10-28 18:44:22 -0400919 Lists all devices and the controllers with roles assigned to them
920 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800922 """
andrewonlab7c211572014-10-15 16:45:20 -0400923 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700926 cmdStr += " -j"
927 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800928 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Jon Hall983a1702014-10-28 18:44:22 -0400936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400939 main.cleanup()
940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400943 main.cleanup()
944 main.exit()
945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800947 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800948 Given the a string containing the json representation of the "roles"
949 cli command and a partial or whole device id, returns a json object
950 containing the roles output for the first device whose id contains
951 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400952
953 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 A dict of the role assignments for the given device or
955 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800956 """
Jon Hall983a1702014-10-28 18:44:22 -0400957 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400959 return None
960 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 rawRoles = self.roles()
962 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800963 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800965 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400967 return device
968 return None
Jon Hallc6793552016-01-19 14:18:37 -0800969 except ( TypeError, ValueError ):
970 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800971 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400972 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800973 main.log.error( self.name + ": EOF exception found" )
974 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400975 main.cleanup()
976 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800977 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800978 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400979 main.cleanup()
980 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800981
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800983 """
Jon Hall94fd0472014-12-08 11:52:42 -0800984 Iterates through each device and checks if there is a master assigned
985 Returns: main.TRUE if each device has a master
986 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800987 """
Jon Hall94fd0472014-12-08 11:52:42 -0800988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 rawRoles = self.roles()
990 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800991 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800993 # print device
994 if device[ 'master' ] == "none":
995 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800996 return main.FALSE
997 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800998 except ( TypeError, ValueError ):
999 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001000 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001001 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001002 main.log.error( self.name + ": EOF exception found" )
1003 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001004 main.cleanup()
1005 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001006 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001007 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001008 main.cleanup()
1009 main.exit()
1010
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001012 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001013 Returns string of paths, and the cost.
1014 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1018 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001019 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001020 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( "Error in getting paths" )
1022 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001023 else:
kelvin8ec71442015-01-15 16:57:00 -08001024 path = handle.split( ";" )[ 0 ]
1025 cost = handle.split( ";" )[ 1 ]
1026 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001027 except AssertionError:
1028 main.log.exception( "" )
1029 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001030 except TypeError:
1031 main.log.exception( self.name + ": Object not as expected" )
1032 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001033 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001034 main.log.error( self.name + ": EOF exception found" )
1035 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001036 main.cleanup()
1037 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001038 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001039 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001040 main.cleanup()
1041 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001042
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001044 """
Jon Hallffb386d2014-11-21 13:43:38 -08001045 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001048 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001050 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr += " -j"
1053 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001054 if handle:
1055 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001056 # TODO: Maybe make this less hardcoded
1057 # ConsistentMap Exceptions
1058 assert "org.onosproject.store.service" not in handle
1059 # Node not leader
1060 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001061 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001062 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001063 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001064 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001065 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001066 except TypeError:
1067 main.log.exception( self.name + ": Object not as expected" )
1068 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001072 main.cleanup()
1073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 main.cleanup()
1077 main.exit()
1078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001109 main.cleanup()
1110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001112 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001113 main.cleanup()
1114 main.exit()
1115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001117 """
1118 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001120
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001123 IMPORTANT:
1124 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001125 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126 Furthermore, it assumes that value of VLAN is '-1'
1127 Description:
kelvin8ec71442015-01-15 16:57:00 -08001128 Converts mininet hosts ( h1, h2, h3... ) into
1129 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1130 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001135 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 hostHex = hex( int( host ) ).zfill( 12 )
1137 hostHex = str( hostHex ).replace( 'x', '0' )
1138 i = iter( str( hostHex ) )
1139 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1140 hostHex = hostHex + "/-1"
1141 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144
Jon Halld4d4b372015-01-28 16:02:41 -08001145 except TypeError:
1146 main.log.exception( self.name + ": Object not as expected" )
1147 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001149 main.log.error( self.name + ": EOF exception found" )
1150 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001151 main.cleanup()
1152 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001154 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001155 main.cleanup()
1156 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001157
Jeremy Songsterff553672016-05-12 17:06:23 -07001158 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001159 """
andrewonlabe6745342014-10-17 14:29:13 -04001160 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 * hostIdOne: ONOS host id for host1
1162 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001163 Optional:
1164 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001165 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001166 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001167 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001168 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001169 Returns:
1170 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001171 """
andrewonlabe6745342014-10-17 14:29:13 -04001172 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001173 cmdStr = "add-host-intent "
1174 if vlanId:
1175 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001176 if setVlan:
1177 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001180 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001181 if re.search( "Error", handle ):
1182 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001183 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001184 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001185 else:
1186 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1188 match = re.search('id=0x([\da-f]+),', handle)
1189 if match:
1190 return match.group()[3:-1]
1191 else:
1192 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001193 main.log.debug( "Response from ONOS was: " +
1194 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001195 return None
Jon Hallc6793552016-01-19 14:18:37 -08001196 except AssertionError:
1197 main.log.exception( "" )
1198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001199 except TypeError:
1200 main.log.exception( self.name + ": Object not as expected" )
1201 return None
andrewonlabe6745342014-10-17 14:29:13 -04001202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( self.name + ": EOF exception found" )
1204 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001205 main.cleanup()
1206 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001209 main.cleanup()
1210 main.exit()
1211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001213 """
andrewonlab7b31d232014-10-24 13:31:47 -04001214 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 * ingressDevice: device id of ingress device
1216 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001217 Optional:
1218 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001219 Description:
1220 Adds an optical intent by specifying an ingress and egress device
1221 Returns:
1222 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 """
andrewonlab7b31d232014-10-24 13:31:47 -04001224 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1226 " " + str( egressDevice )
1227 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001228 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001229 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "Error in adding Optical intent" )
1232 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001233 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 main.log.info( "Optical intent installed between " +
1235 str( ingressDevice ) + " and " +
1236 str( egressDevice ) )
1237 match = re.search('id=0x([\da-f]+),', handle)
1238 if match:
1239 return match.group()[3:-1]
1240 else:
1241 main.log.error( "Error, intent ID not found" )
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except AssertionError:
1244 main.log.exception( "" )
1245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001246 except TypeError:
1247 main.log.exception( self.name + ": Object not as expected" )
1248 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001252 main.cleanup()
1253 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001255 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001256 main.cleanup()
1257 main.exit()
1258
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001260 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 ingressDevice,
1262 egressDevice,
1263 portIngress="",
1264 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001265 ethType="",
1266 ethSrc="",
1267 ethDst="",
1268 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 ipProto="",
1271 ipSrc="",
1272 ipDst="",
1273 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001274 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 vlanId="",
1276 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * ingressDevice: device id of ingress device
1280 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001293 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001294 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001302 options developers provide for point-to-point
1303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001305 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001306 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001307
Jeremy Songsterff553672016-05-12 17:06:23 -07001308 if ethType:
1309 cmd += " --ethType " + str( ethType )
1310 if ethSrc:
1311 cmd += " --ethSrc " + str( ethSrc )
1312 if ethDst:
1313 cmd += " --ethDst " + str( ethDst )
1314 if bandwidth:
1315 cmd += " --bandwidth " + str( bandwidth )
1316 if lambdaAlloc:
1317 cmd += " --lambda "
1318 if ipProto:
1319 cmd += " --ipProto " + str( ipProto )
1320 if ipSrc:
1321 cmd += " --ipSrc " + str( ipSrc )
1322 if ipDst:
1323 cmd += " --ipDst " + str( ipDst )
1324 if tcpSrc:
1325 cmd += " --tcpSrc " + str( tcpSrc )
1326 if tcpDst:
1327 cmd += " --tcpDst " + str( tcpDst )
1328 if vlanId:
1329 cmd += " -v " + str( vlanId )
1330 if setVlan:
1331 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001332
kelvin8ec71442015-01-15 16:57:00 -08001333 # Check whether the user appended the port
1334 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 if "/" in ingressDevice:
1336 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001337 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001338 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001339 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001340 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001341 # Would it make sense to throw an exception and exit
1342 # the test?
1343 return None
andrewonlab36af3822014-11-18 17:48:18 -05001344
kelvin8ec71442015-01-15 16:57:00 -08001345 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 str( ingressDevice ) + "/" +\
1347 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001348
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 if "/" in egressDevice:
1350 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001351 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001353 main.log.error( "You must specify the egress port" )
1354 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001355
kelvin8ec71442015-01-15 16:57:00 -08001356 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 str( egressDevice ) + "/" +\
1358 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001359
kelvin-onlab898a6c62015-01-16 14:13:53 -08001360 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001361 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001362 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001363 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001364 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001365 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001366 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001367 # TODO: print out all the options in this message?
1368 main.log.info( "Point-to-point intent installed between " +
1369 str( ingressDevice ) + " and " +
1370 str( egressDevice ) )
1371 match = re.search('id=0x([\da-f]+),', handle)
1372 if match:
1373 return match.group()[3:-1]
1374 else:
1375 main.log.error( "Error, intent ID not found" )
1376 return None
Jon Hallc6793552016-01-19 14:18:37 -08001377 except AssertionError:
1378 main.log.exception( "" )
1379 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001380 except TypeError:
1381 main.log.exception( self.name + ": Object not as expected" )
1382 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001384 main.log.error( self.name + ": EOF exception found" )
1385 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001386 main.cleanup()
1387 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001388 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001389 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001390 main.cleanup()
1391 main.exit()
1392
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001394 self,
shahshreyac2f97072015-03-19 17:04:29 -07001395 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001397 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 ethType="",
1400 ethSrc="",
1401 ethDst="",
1402 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 ipProto="",
1405 ipSrc="",
1406 ipDst="",
1407 tcpSrc="",
1408 tcpDst="",
1409 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001410 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001411 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001412 setVlan="",
1413 partial=False ):
kelvin8ec71442015-01-15 16:57:00 -08001414 """
shahshreyad0c80432014-12-04 16:56:05 -08001415 Note:
shahshreya70622b12015-03-19 17:19:00 -07001416 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001417 is same. That is, all ingress devices include port numbers
1418 with a "/" or all ingress devices could specify device
1419 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001420 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001421 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001422 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001424 Optional:
1425 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001426 * ethSrc: specify ethSrc ( i.e. src mac addr )
1427 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001428 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001430 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001431 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001432 * ipSrc: specify ip source address
1433 * ipDst: specify ip destination address
1434 * tcpSrc: specify tcp source port
1435 * tcpDst: specify tcp destination port
1436 * setEthSrc: action to Rewrite Source MAC Address
1437 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001438 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001439 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001440 Description:
kelvin8ec71442015-01-15 16:57:00 -08001441 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001442 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 Returns:
1444 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001445
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001447 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001448 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001449 """
shahshreyad0c80432014-12-04 16:56:05 -08001450 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001451 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001452
Jeremy Songsterff553672016-05-12 17:06:23 -07001453 if ethType:
1454 cmd += " --ethType " + str( ethType )
1455 if ethSrc:
1456 cmd += " --ethSrc " + str( ethSrc )
1457 if ethDst:
1458 cmd += " --ethDst " + str( ethDst )
1459 if bandwidth:
1460 cmd += " --bandwidth " + str( bandwidth )
1461 if lambdaAlloc:
1462 cmd += " --lambda "
1463 if ipProto:
1464 cmd += " --ipProto " + str( ipProto )
1465 if ipSrc:
1466 cmd += " --ipSrc " + str( ipSrc )
1467 if ipDst:
1468 cmd += " --ipDst " + str( ipDst )
1469 if tcpSrc:
1470 cmd += " --tcpSrc " + str( tcpSrc )
1471 if tcpDst:
1472 cmd += " --tcpDst " + str( tcpDst )
1473 if setEthSrc:
1474 cmd += " --setEthSrc " + str( setEthSrc )
1475 if setEthDst:
1476 cmd += " --setEthDst " + str( setEthDst )
1477 if vlanId:
1478 cmd += " -v " + str( vlanId )
1479 if setVlan:
1480 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001481 if partial:
1482 cmd += " --partial"
shahshreyad0c80432014-12-04 16:56:05 -08001483
kelvin8ec71442015-01-15 16:57:00 -08001484 # Check whether the user appended the port
1485 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001486
1487 if portIngressList is None:
1488 for ingressDevice in ingressDeviceList:
1489 if "/" in ingressDevice:
1490 cmd += " " + str( ingressDevice )
1491 else:
1492 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001493 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001494 # TODO: perhaps more meaningful return
1495 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001496 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001497 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001498 for ingressDevice, portIngress in zip( ingressDeviceList,
1499 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001500 cmd += " " + \
1501 str( ingressDevice ) + "/" +\
1502 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001503 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001504 main.log.error( "Device list and port list does not " +
1505 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001506 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 if "/" in egressDevice:
1508 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001509 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001511 main.log.error( "You must specify " +
1512 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001513 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001514
kelvin8ec71442015-01-15 16:57:00 -08001515 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 str( egressDevice ) + "/" +\
1517 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001518 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001519 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001520 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001521 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 main.log.error( "Error in adding multipoint-to-singlepoint " +
1523 "intent" )
1524 return None
shahshreyad0c80432014-12-04 16:56:05 -08001525 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001526 match = re.search('id=0x([\da-f]+),', handle)
1527 if match:
1528 return match.group()[3:-1]
1529 else:
1530 main.log.error( "Error, intent ID not found" )
1531 return None
Jon Hallc6793552016-01-19 14:18:37 -08001532 except AssertionError:
1533 main.log.exception( "" )
1534 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001535 except TypeError:
1536 main.log.exception( self.name + ": Object not as expected" )
1537 return None
1538 except pexpect.EOF:
1539 main.log.error( self.name + ": EOF exception found" )
1540 main.log.error( self.name + ": " + self.handle.before )
1541 main.cleanup()
1542 main.exit()
1543 except Exception:
1544 main.log.exception( self.name + ": Uncaught exception!" )
1545 main.cleanup()
1546 main.exit()
1547
1548 def addSinglepointToMultipointIntent(
1549 self,
1550 ingressDevice,
1551 egressDeviceList,
1552 portIngress="",
1553 portEgressList=None,
1554 ethType="",
1555 ethSrc="",
1556 ethDst="",
1557 bandwidth="",
1558 lambdaAlloc=False,
1559 ipProto="",
1560 ipSrc="",
1561 ipDst="",
1562 tcpSrc="",
1563 tcpDst="",
1564 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001565 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001566 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001567 setVlan="",
1568 partial=False ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001569 """
1570 Note:
1571 This function assumes the format of all egress devices
1572 is same. That is, all egress devices include port numbers
1573 with a "/" or all egress devices could specify device
1574 ids and port numbers seperately.
1575 Required:
1576 * EgressDeviceList: List of device ids of egress device
1577 ( Atleast 2 eress devices required in the list )
1578 * ingressDevice: device id of ingress device
1579 Optional:
1580 * ethType: specify ethType
1581 * ethSrc: specify ethSrc ( i.e. src mac addr )
1582 * ethDst: specify ethDst ( i.e. dst mac addr )
1583 * bandwidth: specify bandwidth capacity of link
1584 * lambdaAlloc: if True, intent will allocate lambda
1585 for the specified intent
1586 * ipProto: specify ip protocol
1587 * ipSrc: specify ip source address
1588 * ipDst: specify ip destination address
1589 * tcpSrc: specify tcp source port
1590 * tcpDst: specify tcp destination port
1591 * setEthSrc: action to Rewrite Source MAC Address
1592 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001593 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001594 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001595 Description:
1596 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1597 specifying device id's and optional fields
1598 Returns:
1599 A string of the intent id or None on error
1600
1601 NOTE: This function may change depending on the
1602 options developers provide for singlepoint-to-multipoint
1603 intent via cli
1604 """
1605 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001606 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001607
Jeremy Songsterff553672016-05-12 17:06:23 -07001608 if ethType:
1609 cmd += " --ethType " + str( ethType )
1610 if ethSrc:
1611 cmd += " --ethSrc " + str( ethSrc )
1612 if ethDst:
1613 cmd += " --ethDst " + str( ethDst )
1614 if bandwidth:
1615 cmd += " --bandwidth " + str( bandwidth )
1616 if lambdaAlloc:
1617 cmd += " --lambda "
1618 if ipProto:
1619 cmd += " --ipProto " + str( ipProto )
1620 if ipSrc:
1621 cmd += " --ipSrc " + str( ipSrc )
1622 if ipDst:
1623 cmd += " --ipDst " + str( ipDst )
1624 if tcpSrc:
1625 cmd += " --tcpSrc " + str( tcpSrc )
1626 if tcpDst:
1627 cmd += " --tcpDst " + str( tcpDst )
1628 if setEthSrc:
1629 cmd += " --setEthSrc " + str( setEthSrc )
1630 if setEthDst:
1631 cmd += " --setEthDst " + str( setEthDst )
1632 if vlanId:
1633 cmd += " -v " + str( vlanId )
1634 if setVlan:
1635 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001636 if partial:
1637 cmd += " --partial"
kelvin-onlabb9408212015-04-01 13:34:04 -07001638
1639 # Check whether the user appended the port
1640 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001641
kelvin-onlabb9408212015-04-01 13:34:04 -07001642 if "/" in ingressDevice:
1643 cmd += " " + str( ingressDevice )
1644 else:
1645 if not portIngress:
1646 main.log.error( "You must specify " +
1647 "the Ingress port" )
1648 return main.FALSE
1649
1650 cmd += " " +\
1651 str( ingressDevice ) + "/" +\
1652 str( portIngress )
1653
1654 if portEgressList is None:
1655 for egressDevice in egressDeviceList:
1656 if "/" in egressDevice:
1657 cmd += " " + str( egressDevice )
1658 else:
1659 main.log.error( "You must specify " +
1660 "the egress port" )
1661 # TODO: perhaps more meaningful return
1662 return main.FALSE
1663 else:
1664 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001665 for egressDevice, portEgress in zip( egressDeviceList,
1666 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 cmd += " " + \
1668 str( egressDevice ) + "/" +\
1669 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001670 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001671 main.log.error( "Device list and port list does not " +
1672 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001673 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001674 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001675 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001676 # If error, return error message
1677 if re.search( "Error", handle ):
1678 main.log.error( "Error in adding singlepoint-to-multipoint " +
1679 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001680 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001681 else:
1682 match = re.search('id=0x([\da-f]+),', handle)
1683 if match:
1684 return match.group()[3:-1]
1685 else:
1686 main.log.error( "Error, intent ID not found" )
1687 return None
Jon Hallc6793552016-01-19 14:18:37 -08001688 except AssertionError:
1689 main.log.exception( "" )
1690 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001691 except TypeError:
1692 main.log.exception( self.name + ": Object not as expected" )
1693 return None
shahshreyad0c80432014-12-04 16:56:05 -08001694 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001695 main.log.error( self.name + ": EOF exception found" )
1696 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001697 main.cleanup()
1698 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001699 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001700 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001701 main.cleanup()
1702 main.exit()
1703
Hari Krishna9e232602015-04-13 17:29:08 -07001704 def addMplsIntent(
1705 self,
1706 ingressDevice,
1707 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001708 ingressPort="",
1709 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001710 ethType="",
1711 ethSrc="",
1712 ethDst="",
1713 bandwidth="",
1714 lambdaAlloc=False,
1715 ipProto="",
1716 ipSrc="",
1717 ipDst="",
1718 tcpSrc="",
1719 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001720 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001721 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001722 priority=""):
1723 """
1724 Required:
1725 * ingressDevice: device id of ingress device
1726 * egressDevice: device id of egress device
1727 Optional:
1728 * ethType: specify ethType
1729 * ethSrc: specify ethSrc ( i.e. src mac addr )
1730 * ethDst: specify ethDst ( i.e. dst mac addr )
1731 * bandwidth: specify bandwidth capacity of link
1732 * lambdaAlloc: if True, intent will allocate lambda
1733 for the specified intent
1734 * ipProto: specify ip protocol
1735 * ipSrc: specify ip source address
1736 * ipDst: specify ip destination address
1737 * tcpSrc: specify tcp source port
1738 * tcpDst: specify tcp destination port
1739 * ingressLabel: Ingress MPLS label
1740 * egressLabel: Egress MPLS label
1741 Description:
1742 Adds MPLS intent by
1743 specifying device id's and optional fields
1744 Returns:
1745 A string of the intent id or None on error
1746
1747 NOTE: This function may change depending on the
1748 options developers provide for MPLS
1749 intent via cli
1750 """
1751 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001752 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001753
Jeremy Songsterff553672016-05-12 17:06:23 -07001754 if ethType:
1755 cmd += " --ethType " + str( ethType )
1756 if ethSrc:
1757 cmd += " --ethSrc " + str( ethSrc )
1758 if ethDst:
1759 cmd += " --ethDst " + str( ethDst )
1760 if bandwidth:
1761 cmd += " --bandwidth " + str( bandwidth )
1762 if lambdaAlloc:
1763 cmd += " --lambda "
1764 if ipProto:
1765 cmd += " --ipProto " + str( ipProto )
1766 if ipSrc:
1767 cmd += " --ipSrc " + str( ipSrc )
1768 if ipDst:
1769 cmd += " --ipDst " + str( ipDst )
1770 if tcpSrc:
1771 cmd += " --tcpSrc " + str( tcpSrc )
1772 if tcpDst:
1773 cmd += " --tcpDst " + str( tcpDst )
1774 if ingressLabel:
1775 cmd += " --ingressLabel " + str( ingressLabel )
1776 if egressLabel:
1777 cmd += " --egressLabel " + str( egressLabel )
1778 if priority:
1779 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001780
1781 # Check whether the user appended the port
1782 # or provided it as an input
1783 if "/" in ingressDevice:
1784 cmd += " " + str( ingressDevice )
1785 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001786 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001787 main.log.error( "You must specify the ingress port" )
1788 return None
1789
1790 cmd += " " + \
1791 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001792 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001793
1794 if "/" in egressDevice:
1795 cmd += " " + str( egressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the egress port" )
1799 return None
1800
1801 cmd += " " +\
1802 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001806 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001807 # If error, return error message
1808 if re.search( "Error", handle ):
1809 main.log.error( "Error in adding mpls intent" )
1810 return None
1811 else:
1812 # TODO: print out all the options in this message?
1813 main.log.info( "MPLS intent installed between " +
1814 str( ingressDevice ) + " and " +
1815 str( egressDevice ) )
1816 match = re.search('id=0x([\da-f]+),', handle)
1817 if match:
1818 return match.group()[3:-1]
1819 else:
1820 main.log.error( "Error, intent ID not found" )
1821 return None
Jon Hallc6793552016-01-19 14:18:37 -08001822 except AssertionError:
1823 main.log.exception( "" )
1824 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
1828 except pexpect.EOF:
1829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
1831 main.cleanup()
1832 main.exit()
1833 except Exception:
1834 main.log.exception( self.name + ": Uncaught exception!" )
1835 main.cleanup()
1836 main.exit()
1837
Jon Hallefbd9792015-03-05 16:11:36 -08001838 def removeIntent( self, intentId, app='org.onosproject.cli',
1839 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001840 """
shahshreya1c818fc2015-02-26 13:44:08 -08001841 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001842 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001843 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001844 -p or --purge: Purge the intent from the store after removal
1845
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001847 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001848 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001851 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001852 if purge:
1853 cmdStr += " -p"
1854 if sync:
1855 cmdStr += " -s"
1856
1857 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001859 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001860 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001863 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 # TODO: Should this be main.TRUE
1865 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001866 except AssertionError:
1867 main.log.exception( "" )
1868 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 main.cleanup()
1880 main.exit()
1881
YPZhangfebf7302016-05-24 16:45:56 -07001882 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001883 """
1884 Description:
1885 Remove all the intents
1886 Optional args:-
1887 -s or --sync: Waits for the removal before returning
1888 -p or --purge: Purge the intent from the store after removal
1889 Returns:
1890 Returns main.TRUE if all intents are removed, otherwise returns
1891 main.FALSE; Returns None for exception
1892 """
1893 try:
1894 cmdStr = "remove-intent"
1895 if purge:
1896 cmdStr += " -p"
1897 if sync:
1898 cmdStr += " -s"
1899
1900 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001901 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001902 assert "Command not found:" not in handle, handle
1903 if re.search( "Error", handle ):
1904 main.log.error( "Error in removing intent" )
1905 return main.FALSE
1906 else:
1907 return main.TRUE
1908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
1911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
1914 except pexpect.EOF:
1915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
1917 main.cleanup()
1918 main.exit()
1919 except Exception:
1920 main.log.exception( self.name + ": Uncaught exception!" )
1921 main.cleanup()
1922 main.exit()
1923
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001924 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001925 """
1926 Purges all WITHDRAWN Intents
1927 """
1928 try:
1929 cmdStr = "purge-intents"
1930 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001931 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 if re.search( "Error", handle ):
1933 main.log.error( "Error in purging intents" )
1934 return main.FALSE
1935 else:
1936 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001937 except AssertionError:
1938 main.log.exception( "" )
1939 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 except TypeError:
1941 main.log.exception( self.name + ": Object not as expected" )
1942 return None
1943 except pexpect.EOF:
1944 main.log.error( self.name + ": EOF exception found" )
1945 main.log.error( self.name + ": " + self.handle.before )
1946 main.cleanup()
1947 main.exit()
1948 except Exception:
1949 main.log.exception( self.name + ": Uncaught exception!" )
1950 main.cleanup()
1951 main.exit()
1952
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001954 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001955 NOTE: This method should be used after installing application:
1956 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001957 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 Description:
1960 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001961 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001965 cmdStr += " -j"
1966 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001967 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001969 except AssertionError:
1970 main.log.exception( "" )
1971 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001972 except TypeError:
1973 main.log.exception( self.name + ": Object not as expected" )
1974 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001976 main.log.error( self.name + ": EOF exception found" )
1977 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 main.cleanup()
1979 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001981 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 main.cleanup()
1983 main.exit()
1984
pingping-lin54b03372015-08-13 14:43:10 -07001985 def ipv4RouteNumber( self ):
1986 """
1987 NOTE: This method should be used after installing application:
1988 onos-app-sdnip
1989 Description:
1990 Obtain the total IPv4 routes number in the system
1991 """
1992 try:
1993 cmdStr = "routes -s -j"
1994 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001995 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001996 jsonResult = json.loads( handle )
1997 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001998 except AssertionError:
1999 main.log.exception( "" )
2000 return None
2001 except ( TypeError, ValueError ):
2002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception!" )
2011 main.cleanup()
2012 main.exit()
2013
pingping-lin8244a3b2015-09-16 13:36:56 -07002014 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002015 """
andrewonlabe6745342014-10-17 14:29:13 -04002016 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002017 Obtain intents from the ONOS cli.
2018 Optional:
2019 * jsonFormat: Enable output formatting in json, default to True
2020 * summary: Whether only output the intent summary, defaults to False
2021 * type: Only output a certain type of intent. This options is valid
2022 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 """
andrewonlabe6745342014-10-17 14:29:13 -04002024 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002025 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 if summary:
2027 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002029 cmdStr += " -j"
2030 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002031 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002032 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002033 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002034 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002035 else:
Jon Hallff566d52016-01-15 14:45:36 -08002036 intentType = ""
2037 # IF we want the summary of a specific intent type
2038 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002040 if intentType in jsonResult.keys():
2041 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002042 else:
Jon Hallff566d52016-01-15 14:45:36 -08002043 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002044 return handle
2045 else:
2046 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
2050 except ( TypeError, ValueError ):
2051 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002052 return None
2053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
2056 main.cleanup()
2057 main.exit()
2058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
2060 main.cleanup()
2061 main.exit()
2062
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 def getIntentState(self, intentsId, intentsJson=None):
2064 """
You Wangfdcbfc42016-05-16 12:16:53 -07002065 Description:
2066 Gets intent state. Accepts a single intent ID (string type) or a
2067 list of intent IDs.
2068 Parameters:
2069 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002071 Returns:
2072 Returns the state (string type) of the ID if a single intent ID is
2073 accepted.
2074 Returns a list of dictionaries if a list of intent IDs is accepted,
2075 and each dictionary maps 'id' to the Intent ID and 'state' to
2076 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002078 try:
2079 state = "State is Undefined"
2080 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002081 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002082 else:
Jon Hallc6793552016-01-19 14:18:37 -08002083 rawJson = intentsJson
2084 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002085 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002086 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002087 if intentsId == intent[ 'id' ]:
2088 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002090 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2091 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002092 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002093 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002094 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002095 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002096 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002097 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 if intentsId[ i ] == intents[ 'id' ]:
2099 stateDict[ 'state' ] = intents[ 'state' ]
2100 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002101 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 break
Jon Hallefbd9792015-03-05 16:11:36 -08002103 if len( intentsId ) != len( dictList ):
2104 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002105 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002107 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 return None
Jon Hallc6793552016-01-19 14:18:37 -08002109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
2115 main.cleanup()
2116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002117 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002119 main.cleanup()
2120 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002121
kelvin-onlabf512e942015-06-08 19:42:59 -07002122 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 Description:
2125 Check intents state
2126 Required:
2127 intentsId - List of intents ID to be checked
2128 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 expectedState - Check the expected state(s) of each intents
2130 state in the list.
2131 *NOTE: You can pass in a list of expected state,
2132 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002134 Returns main.TRUE only if all intent are the same as expected states
2135 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 """
2137 try:
2138 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002139 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002142 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 "getting intents state" )
2144 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002145
2146 if isinstance( expectedState, types.StringType ):
2147 for intents in intentsDict:
2148 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002149 main.log.debug( self.name + " : Intent ID - " +
2150 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002151 " actual state = " +
2152 intents.get( 'state' )
2153 + " does not equal expected state = "
2154 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002155 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002156
2157 elif isinstance( expectedState, types.ListType ):
2158 for intents in intentsDict:
2159 if not any( state == intents.get( 'state' ) for state in
2160 expectedState ):
2161 main.log.debug( self.name + " : Intent ID - " +
2162 intents.get( 'id' ) +
2163 " actual state = " +
2164 intents.get( 'state' ) +
2165 " does not equal expected states = "
2166 + str( expectedState ) )
2167 returnValue = main.FALSE
2168
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002169 if returnValue == main.TRUE:
2170 main.log.info( self.name + ": All " +
2171 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002172 " intents are in " + str( expectedState ) +
2173 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002174 return returnValue
2175 except TypeError:
2176 main.log.exception( self.name + ": Object not as expected" )
2177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
2181 main.cleanup()
2182 main.exit()
2183 except Exception:
2184 main.log.exception( self.name + ": Uncaught exception!" )
2185 main.cleanup()
2186 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002187
You Wang66518af2016-05-16 15:32:59 -07002188 def compareIntent( self, intentDict ):
2189 """
2190 Description:
2191 Compare the intent ids and states provided in the argument with all intents in ONOS
2192 Return:
2193 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2194 Arguments:
2195 intentDict: a dictionary which maps intent ids to intent states
2196 """
2197 try:
2198 intentsRaw = self.intents()
2199 intentsJson = json.loads( intentsRaw )
2200 intentDictONOS = {}
2201 for intent in intentsJson:
2202 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2203 if len( intentDict ) != len( intentDictONOS ):
2204 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2205 str( len( intentDict ) ) + " expected and " +
2206 str( len( intentDictONOS ) ) + " actual" )
2207 return main.FALSE
2208 returnValue = main.TRUE
2209 for intentID in intentDict.keys():
2210 if not intentID in intentDictONOS.keys():
2211 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2212 returnValue = main.FALSE
2213 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2214 main.log.debug( self.name + ": intent ID - " + intentID +
2215 " expected state is " + intentDict[ intentID ] +
2216 " but actual state is " + intentDictONOS[ intentID ] )
2217 returnValue = main.FALSE
2218 if returnValue == main.TRUE:
2219 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2220 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002221 except KeyError:
2222 main.log.exception( self.name + ": KeyError exception found" )
2223 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002224 except ( TypeError, ValueError ):
2225 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002226 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002227 except pexpect.EOF:
2228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
2230 main.cleanup()
2231 main.exit()
2232 except Exception:
2233 main.log.exception( self.name + ": Uncaught exception!" )
2234 main.cleanup()
2235 main.exit()
2236
GlennRCed771242016-01-13 17:02:47 -08002237 def checkIntentSummary( self, timeout=60 ):
2238 """
2239 Description:
2240 Check the number of installed intents.
2241 Optional:
2242 timeout - the timeout for pexcept
2243 Return:
2244 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2245 , otherwise, returns main.FALSE.
2246 """
2247
2248 try:
2249 cmd = "intents -s -j"
2250
2251 # Check response if something wrong
2252 response = self.sendline( cmd, timeout=timeout )
2253 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002254 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002255 response = json.loads( response )
2256
2257 # get total and installed number, see if they are match
2258 allState = response.get( 'all' )
2259 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002260 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002261 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002262 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002263 return main.FALSE
2264
Jon Hallc6793552016-01-19 14:18:37 -08002265 except ( TypeError, ValueError ):
2266 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002267 return None
2268 except pexpect.EOF:
2269 main.log.error( self.name + ": EOF exception found" )
2270 main.log.error( self.name + ": " + self.handle.before )
2271 main.cleanup()
2272 main.exit()
2273 except Exception:
2274 main.log.exception( self.name + ": Uncaught exception!" )
2275 main.cleanup()
2276 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002277 except pexpect.TIMEOUT:
2278 main.log.error( self.name + ": ONOS timeout" )
2279 return None
GlennRCed771242016-01-13 17:02:47 -08002280
YPZhangebf9eb52016-05-12 15:20:24 -07002281 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002282 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002283 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002284 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002285 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002287 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002288 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002289 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002291 cmdStr += " -j "
2292 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002293 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002294 assert "Command not found:" not in handle, handle
2295 if re.search( "Error:", handle ):
2296 main.log.error( self.name + ": flows() response: " +
2297 str( handle ) )
2298 return handle
2299 except AssertionError:
2300 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002301 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002302 except TypeError:
2303 main.log.exception( self.name + ": Object not as expected" )
2304 return None
Jon Hallc6793552016-01-19 14:18:37 -08002305 except pexpect.TIMEOUT:
2306 main.log.error( self.name + ": ONOS timeout" )
2307 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002309 main.log.error( self.name + ": EOF exception found" )
2310 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002311 main.cleanup()
2312 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002313 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002314 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002315 main.cleanup()
2316 main.exit()
2317
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002318 def checkFlowCount(self, min=0, timeout=60 ):
2319 count = int(self.getTotalFlowsNum( timeout=timeout ))
2320 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002321
YPZhangebf9eb52016-05-12 15:20:24 -07002322 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002323 """
2324 Description:
GlennRCed771242016-01-13 17:02:47 -08002325 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002326 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2327 if the count of those states is 0, which means all current flows
2328 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002329 Optional:
GlennRCed771242016-01-13 17:02:47 -08002330 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002331 Return:
2332 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002333 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002334 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002335 """
2336 try:
GlennRCed771242016-01-13 17:02:47 -08002337 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2338 checkedStates = []
2339 statesCount = [0, 0, 0, 0]
2340 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002341 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002342 if rawFlows:
2343 # if we didn't get flows or flows function return None, we should return
2344 # main.Flase
2345 checkedStates.append( json.loads( rawFlows ) )
2346 else:
2347 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002348 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002349 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002350 try:
2351 statesCount[i] += int( c.get( "flowCount" ) )
2352 except TypeError:
2353 main.log.exception( "Json object not as expected" )
2354 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002355
GlennRCed771242016-01-13 17:02:47 -08002356 # We want to count PENDING_ADD if isPENDING is true
2357 if isPENDING:
2358 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2359 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002360 else:
GlennRCed771242016-01-13 17:02:47 -08002361 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2362 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002363 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002364 except ( TypeError, ValueError ):
2365 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002366 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002367
YPZhang240842b2016-05-17 12:00:50 -07002368 except AssertionError:
2369 main.log.exception( "" )
2370 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002371 except pexpect.EOF:
2372 main.log.error( self.name + ": EOF exception found" )
2373 main.log.error( self.name + ": " + self.handle.before )
2374 main.cleanup()
2375 main.exit()
2376 except Exception:
2377 main.log.exception( self.name + ": Uncaught exception!" )
2378 main.cleanup()
2379 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002380 except pexpect.TIMEOUT:
2381 main.log.error( self.name + ": ONOS timeout" )
2382 return None
2383
kelvin-onlab4df89f22015-04-13 18:10:23 -07002384
GlennRCed771242016-01-13 17:02:47 -08002385 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002386 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002387 """
andrewonlab87852b02014-11-19 18:44:19 -05002388 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002389 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002390 a specific point-to-point intent definition
2391 Required:
GlennRCed771242016-01-13 17:02:47 -08002392 * ingress: specify source dpid
2393 * egress: specify destination dpid
2394 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002395 Optional:
GlennRCed771242016-01-13 17:02:47 -08002396 * offset: the keyOffset is where the next batch of intents
2397 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002398 * noExit: If set to True, TestON will not exit if any error when issus command
2399 * getResponse: If set to True, function will return ONOS response.
2400
GlennRCed771242016-01-13 17:02:47 -08002401 Returns: If failed to push test intents, it will returen None,
2402 if successful, return true.
2403 Timeout expection will return None,
2404 TypeError will return false
2405 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002406 """
andrewonlab87852b02014-11-19 18:44:19 -05002407 try:
GlennRCed771242016-01-13 17:02:47 -08002408 if background:
2409 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002410 else:
GlennRCed771242016-01-13 17:02:47 -08002411 back = ""
2412 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002413 ingress,
2414 egress,
2415 batchSize,
2416 offset,
2417 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002418 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002419 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002420 main.log.info( response )
2421 if response == None:
2422 return None
2423
YPZhangb34b7e12016-06-14 14:28:19 -07002424 if getResponse:
2425 return response
2426
GlennRCed771242016-01-13 17:02:47 -08002427 # TODO: We should handle if there is failure in installation
2428 return main.TRUE
2429
Jon Hallc6793552016-01-19 14:18:37 -08002430 except AssertionError:
2431 main.log.exception( "" )
2432 return None
GlennRCed771242016-01-13 17:02:47 -08002433 except pexpect.TIMEOUT:
2434 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002435 return None
andrewonlab87852b02014-11-19 18:44:19 -05002436 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002439 main.cleanup()
2440 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002441 except TypeError:
2442 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002443 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002445 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002446 main.cleanup()
2447 main.exit()
2448
YPZhangebf9eb52016-05-12 15:20:24 -07002449 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002450 """
2451 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002452 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002453 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002454 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002455 """
YPZhange3109a72016-02-02 11:25:37 -08002456
YPZhangb5d3f832016-01-23 22:54:26 -08002457 try:
YPZhange3109a72016-02-02 11:25:37 -08002458 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002459 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002460 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002461
2462 if totalFlows == None:
2463 # if timeout, we will get total number of all flows, and subtract other states
2464 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2465 checkedStates = []
2466 totalFlows = 0
2467 statesCount = [0, 0, 0, 0]
2468
2469 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002470 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002471 totalFlows = int( response.get("flows") )
2472
2473 for s in states:
2474 rawFlows = self.flows( state=s, timeout = timeout )
2475 if rawFlows == None:
2476 # if timeout, return the total flows number from summary command
2477 return totalFlows
2478 checkedStates.append( json.loads( rawFlows ) )
2479
2480 # Calculate ADDED flows number, equal total subtracts others
2481 for i in range( len( states ) ):
2482 for c in checkedStates[i]:
2483 try:
2484 statesCount[i] += int( c.get( "flowCount" ) )
2485 except TypeError:
2486 main.log.exception( "Json object not as expected" )
2487 totalFlows = totalFlows - int( statesCount[i] )
2488 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2489
2490 return totalFlows
2491
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002492 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002493
You Wangd3cb2ce2016-05-16 14:01:24 -07002494 except ( TypeError, ValueError ):
2495 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002496 return None
2497 except pexpect.EOF:
2498 main.log.error( self.name + ": EOF exception found" )
2499 main.log.error( self.name + ": " + self.handle.before )
2500 main.cleanup()
2501 main.exit()
2502 except Exception:
2503 main.log.exception( self.name + ": Uncaught exception!" )
2504 main.cleanup()
2505 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002506 except pexpect.TIMEOUT:
2507 main.log.error( self.name + ": ONOS timeout" )
2508 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002509
YPZhangebf9eb52016-05-12 15:20:24 -07002510 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002511 """
2512 Description:
2513 Get the total number of intents, include every states.
2514 Return:
2515 The number of intents
2516 """
2517 try:
2518 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002519 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002520 if response == None:
2521 return -1
2522 response = json.loads( response )
2523 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002524 except ( TypeError, ValueError ):
2525 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002526 return None
2527 except pexpect.EOF:
2528 main.log.error( self.name + ": EOF exception found" )
2529 main.log.error( self.name + ": " + self.handle.before )
2530 main.cleanup()
2531 main.exit()
2532 except Exception:
2533 main.log.exception( self.name + ": Uncaught exception!" )
2534 main.cleanup()
2535 main.exit()
2536
kelvin-onlabd3b64892015-01-20 13:26:24 -08002537 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002538 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002539 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002540 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002542 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002543 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002544 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002545 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002546 cmdStr += " -j"
2547 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002548 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002549 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002550 except AssertionError:
2551 main.log.exception( "" )
2552 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002553 except TypeError:
2554 main.log.exception( self.name + ": Object not as expected" )
2555 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002557 main.log.error( self.name + ": EOF exception found" )
2558 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002559 main.cleanup()
2560 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002561 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002562 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002563 main.cleanup()
2564 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002565
kelvin-onlabd3b64892015-01-20 13:26:24 -08002566 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002567 """
2568 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002569 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002570 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002571 """
andrewonlab867212a2014-10-22 20:13:38 -04002572 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002573 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002574 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002575 cmdStr += " -j"
2576 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002577 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002578 if handle:
2579 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002580 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002581 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002582 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002583 else:
2584 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002585 except AssertionError:
2586 main.log.exception( "" )
2587 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002588 except TypeError:
2589 main.log.exception( self.name + ": Object not as expected" )
2590 return None
andrewonlab867212a2014-10-22 20:13:38 -04002591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002592 main.log.error( self.name + ": EOF exception found" )
2593 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002594 main.cleanup()
2595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002597 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002598 main.cleanup()
2599 main.exit()
2600
kelvin8ec71442015-01-15 16:57:00 -08002601 # Wrapper functions ****************
2602 # Wrapper functions use existing driver
2603 # functions and extends their use case.
2604 # For example, we may use the output of
2605 # a normal driver function, and parse it
2606 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002607
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002609 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002610 Description:
2611 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002612 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002613 try:
kelvin8ec71442015-01-15 16:57:00 -08002614 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002615 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002616 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002617
kelvin8ec71442015-01-15 16:57:00 -08002618 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002619 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2620 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002621 match = re.search('id=0x([\da-f]+),', intents)
2622 if match:
2623 tmpId = match.group()[3:-1]
2624 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002625 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002626
Jon Halld4d4b372015-01-28 16:02:41 -08002627 except TypeError:
2628 main.log.exception( self.name + ": Object not as expected" )
2629 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002631 main.log.error( self.name + ": EOF exception found" )
2632 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002633 main.cleanup()
2634 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002635 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002636 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002637 main.cleanup()
2638 main.exit()
2639
Jon Hall30b82fa2015-03-04 17:15:43 -08002640 def FlowAddedCount( self, deviceId ):
2641 """
2642 Determine the number of flow rules for the given device id that are
2643 in the added state
2644 """
2645 try:
2646 cmdStr = "flows any " + str( deviceId ) + " | " +\
2647 "grep 'state=ADDED' | wc -l"
2648 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002649 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002650 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002651 except AssertionError:
2652 main.log.exception( "" )
2653 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002654 except pexpect.EOF:
2655 main.log.error( self.name + ": EOF exception found" )
2656 main.log.error( self.name + ": " + self.handle.before )
2657 main.cleanup()
2658 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002659 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002660 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002661 main.cleanup()
2662 main.exit()
2663
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002665 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002666 Use 'devices' function to obtain list of all devices
2667 and parse the result to obtain a list of all device
2668 id's. Returns this list. Returns empty list if no
2669 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002670 List is ordered sequentially
2671
andrewonlab3e15ead2014-10-15 14:21:34 -04002672 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002673 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002674 the ids. By obtaining the list of device ids on the fly,
2675 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002676 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002677 try:
kelvin8ec71442015-01-15 16:57:00 -08002678 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 devicesStr = self.devices( jsonFormat=False )
2680 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002681
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002683 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 return idList
kelvin8ec71442015-01-15 16:57:00 -08002685
2686 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002687 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002688 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002689 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002690 # Split list further into arguments before and after string
2691 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 # append to idList
2693 for arg in tempList:
2694 idList.append( arg.split( "id=" )[ 1 ] )
2695 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002696
Jon Halld4d4b372015-01-28 16:02:41 -08002697 except TypeError:
2698 main.log.exception( self.name + ": Object not as expected" )
2699 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002703 main.cleanup()
2704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002706 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002707 main.cleanup()
2708 main.exit()
2709
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002711 """
andrewonlab7c211572014-10-15 16:45:20 -04002712 Uses 'nodes' function to obtain list of all nodes
2713 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002714 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002715 Returns:
2716 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002717 """
andrewonlab7c211572014-10-15 16:45:20 -04002718 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002719 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002721 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002722 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002724 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002726 nodesJson = json.loads( nodesStr )
2727 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002728 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002729 except ( TypeError, ValueError ):
2730 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002731 return None
andrewonlab7c211572014-10-15 16:45:20 -04002732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002735 main.cleanup()
2736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002737 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002738 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002739 main.cleanup()
2740 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002741
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002743 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002744 Return the first device from the devices api whose 'id' contains 'dpid'
2745 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002746 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002747 try:
kelvin8ec71442015-01-15 16:57:00 -08002748 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002749 return None
2750 else:
kelvin8ec71442015-01-15 16:57:00 -08002751 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002752 rawDevices = self.devices()
2753 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002754 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002756 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2757 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002758 return device
2759 return None
Jon Hallc6793552016-01-19 14:18:37 -08002760 except ( TypeError, ValueError ):
2761 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002762 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002766 main.cleanup()
2767 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002768 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002769 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002770 main.cleanup()
2771 main.exit()
2772
You Wang24139872016-05-03 11:48:47 -07002773 def getTopology( self, topologyOutput ):
2774 """
2775 Definition:
2776 Loads a json topology output
2777 Return:
2778 topology = current ONOS topology
2779 """
2780 import json
2781 try:
2782 # either onos:topology or 'topology' will work in CLI
2783 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002784 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002785 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002786 except ( TypeError, ValueError ):
2787 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2788 return None
You Wang24139872016-05-03 11:48:47 -07002789 except pexpect.EOF:
2790 main.log.error( self.name + ": EOF exception found" )
2791 main.log.error( self.name + ": " + self.handle.before )
2792 main.cleanup()
2793 main.exit()
2794 except Exception:
2795 main.log.exception( self.name + ": Uncaught exception!" )
2796 main.cleanup()
2797 main.exit()
2798
Flavio Castro82ee2f62016-06-07 15:04:12 -07002799 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002800 """
Jon Hallefbd9792015-03-05 16:11:36 -08002801 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002802 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002803 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002804
Flavio Castro82ee2f62016-06-07 15:04:12 -07002805 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002806 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002807 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002808 logLevel = level to log to.
2809 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002810
Jon Hallefbd9792015-03-05 16:11:36 -08002811 Returns: main.TRUE if the number of switches and links are correct,
2812 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002813 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002814 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002815 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002816 try:
You Wang13310252016-07-31 10:56:14 -07002817 summary = self.summary()
2818 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002819 except ( TypeError, ValueError ):
2820 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2821 return main.ERROR
2822 try:
2823 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002824 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002825 return main.ERROR
2826 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002827 # Is the number of switches is what we expected
2828 devices = topology.get( 'devices', False )
2829 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002830 nodes = summary.get( 'nodes', False )
2831 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002832 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002833 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002834 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002835 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002836 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2837 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002838 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002839 output = output + "The number of links and switches match "\
2840 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002841 result = main.TRUE
2842 else:
You Wang24139872016-05-03 11:48:47 -07002843 output = output + \
2844 "The number of links and switches does not match " + \
2845 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002846 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002847 output = output + "\n ONOS sees %i devices" % int( devices )
2848 output = output + " (%i expected) " % int( numoswitch )
2849 output = output + "and %i links " % int( links )
2850 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002851 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002852 output = output + "and %i controllers " % int( nodes )
2853 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002854 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002855 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002857 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002858 else:
You Wang24139872016-05-03 11:48:47 -07002859 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002860 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002864 main.cleanup()
2865 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002867 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002868 main.cleanup()
2869 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002870
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002872 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002873 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002874 deviceId must be the id of a device as seen in the onos devices command
2875 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002876 role must be either master, standby, or none
2877
Jon Halle3f39ff2015-01-13 11:50:53 -08002878 Returns:
2879 main.TRUE or main.FALSE based on argument verification and
2880 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002881 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002882 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002883 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002884 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 cmdStr = "device-role " +\
2886 str( deviceId ) + " " +\
2887 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002888 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002889 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002890 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002891 if re.search( "Error", handle ):
2892 # end color output to escape any colours
2893 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002894 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002896 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002897 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002898 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002899 main.log.error( "Invalid 'role' given to device_role(). " +
2900 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002901 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002902 except AssertionError:
2903 main.log.exception( "" )
2904 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002905 except TypeError:
2906 main.log.exception( self.name + ": Object not as expected" )
2907 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002909 main.log.error( self.name + ": EOF exception found" )
2910 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002911 main.cleanup()
2912 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002913 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002914 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002915 main.cleanup()
2916 main.exit()
2917
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002919 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002920 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002921 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002923 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002924 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002925 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002927 cmdStr += " -j"
2928 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002929 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002930 return handle
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 Hall73cf9cc2014-11-20 22:28:38 -08002937 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 Hall73cf9cc2014-11-20 22:28:38 -08002940 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 Hall73cf9cc2014-11-20 22:28:38 -08002944 main.cleanup()
2945 main.exit()
2946
kelvin-onlabd3b64892015-01-20 13:26:24 -08002947 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002948 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002949 CLI command to get the current leader for the Election test application
2950 NOTE: Requires installation of the onos-app-election feature
2951 Returns: Node IP of the leader if one exists
2952 None if none exists
2953 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002954 """
Jon Hall94fd0472014-12-08 11:52:42 -08002955 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002956 cmdStr = "election-test-leader"
2957 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002958 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002959 # Leader
2960 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002961 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002962 nodeSearch = re.search( leaderPattern, response )
2963 if nodeSearch:
2964 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002965 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002966 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002967 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002968 # no leader
2969 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002970 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002971 nullSearch = re.search( nullPattern, response )
2972 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002973 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002974 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002975 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002976 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07002977 main.log.error( "Error in electionTestLeader on " + self.name +
2978 ": " + "unexpected response" )
2979 main.log.error( repr( response ) )
2980 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002981 except AssertionError:
2982 main.log.exception( "" )
2983 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002984 except TypeError:
2985 main.log.exception( self.name + ": Object not as expected" )
2986 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002988 main.log.error( self.name + ": EOF exception found" )
2989 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002990 main.cleanup()
2991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002992 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002993 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002994 main.cleanup()
2995 main.exit()
2996
kelvin-onlabd3b64892015-01-20 13:26:24 -08002997 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002998 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002999 CLI command to run for leadership of the Election test application.
3000 NOTE: Requires installation of the onos-app-election feature
3001 Returns: Main.TRUE on success
3002 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 """
Jon Hall94fd0472014-12-08 11:52:42 -08003004 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003005 cmdStr = "election-test-run"
3006 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003007 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003009 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003010 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003011 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003012 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003013 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003014 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003015 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003016 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003017 main.log.error( "Error in electionTestRun on " + self.name +
3018 ": " + "unexpected response" )
3019 main.log.error( repr( response ) )
3020 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003021 except AssertionError:
3022 main.log.exception( "" )
3023 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003024 except TypeError:
3025 main.log.exception( self.name + ": Object not as expected" )
3026 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003027 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003028 main.log.error( self.name + ": EOF exception found" )
3029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003030 main.cleanup()
3031 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003032 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003033 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003034 main.cleanup()
3035 main.exit()
3036
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003038 """
Jon Hall94fd0472014-12-08 11:52:42 -08003039 * CLI command to withdraw the local node from leadership election for
3040 * the Election test application.
3041 #NOTE: Requires installation of the onos-app-election feature
3042 Returns: Main.TRUE on success
3043 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003044 """
Jon Hall94fd0472014-12-08 11:52:42 -08003045 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003046 cmdStr = "election-test-withdraw"
3047 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003048 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003049 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003051 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003052 if re.search( successPattern, response ):
3053 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003054 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003055 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003056 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003057 main.log.error( "Error in electionTestWithdraw on " +
3058 self.name + ": " + "unexpected response" )
3059 main.log.error( repr( response ) )
3060 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003061 except AssertionError:
3062 main.log.exception( "" )
3063 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003064 except TypeError:
3065 main.log.exception( self.name + ": Object not as expected" )
3066 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003068 main.log.error( self.name + ": EOF exception found" )
3069 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003070 main.cleanup()
3071 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003072 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003073 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003074 main.cleanup()
3075 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003076
kelvin8ec71442015-01-15 16:57:00 -08003077 def getDevicePortsEnabledCount( self, dpid ):
3078 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003079 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003080 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003081 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003082 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003083 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3084 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003085 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003086 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003087 if re.search( "No such device", output ):
3088 main.log.error( "Error in getting ports" )
3089 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003090 return output
Jon Hallc6793552016-01-19 14:18:37 -08003091 except AssertionError:
3092 main.log.exception( "" )
3093 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003094 except TypeError:
3095 main.log.exception( self.name + ": Object not as expected" )
3096 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003097 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003098 main.log.error( self.name + ": EOF exception found" )
3099 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003100 main.cleanup()
3101 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003102 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003103 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003104 main.cleanup()
3105 main.exit()
3106
kelvin8ec71442015-01-15 16:57:00 -08003107 def getDeviceLinksActiveCount( self, dpid ):
3108 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003109 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003110 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003111 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003112 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003113 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3114 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003115 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003116 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003117 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 main.log.error( "Error in getting ports " )
3119 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003120 return output
Jon Hallc6793552016-01-19 14:18:37 -08003121 except AssertionError:
3122 main.log.exception( "" )
3123 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003124 except TypeError:
3125 main.log.exception( self.name + ": Object not as expected" )
3126 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003128 main.log.error( self.name + ": EOF exception found" )
3129 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 main.cleanup()
3131 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003133 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003134 main.cleanup()
3135 main.exit()
3136
kelvin8ec71442015-01-15 16:57:00 -08003137 def getAllIntentIds( self ):
3138 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003142 cmdStr = "onos:intents | grep id="
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( "Error", output ):
3147 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!" )
3163 main.cleanup()
3164 main.exit()
3165
Jon Hall73509952015-02-24 16:42:56 -08003166 def intentSummary( self ):
3167 """
Jon Hallefbd9792015-03-05 16:11:36 -08003168 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003169 """
3170 try:
3171 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003172 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003173 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003174 states.append( intent.get( 'state', None ) )
3175 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003176 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003177 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003178 except ( TypeError, ValueError ):
3179 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003180 return None
3181 except pexpect.EOF:
3182 main.log.error( self.name + ": EOF exception found" )
3183 main.log.error( self.name + ": " + self.handle.before )
3184 main.cleanup()
3185 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003186 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003187 main.log.exception( self.name + ": Uncaught exception!" )
3188 main.cleanup()
3189 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003190
Jon Hall61282e32015-03-19 11:34:11 -07003191 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003192 """
3193 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003194 Optional argument:
3195 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003196 """
Jon Hall63604932015-02-26 17:09:50 -08003197 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003198 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003199 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003200 cmdStr += " -j"
3201 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003202 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003203 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003204 return output
Jon Hallc6793552016-01-19 14:18:37 -08003205 except AssertionError:
3206 main.log.exception( "" )
3207 return None
Jon Hall63604932015-02-26 17:09:50 -08003208 except TypeError:
3209 main.log.exception( self.name + ": Object not as expected" )
3210 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003211 except pexpect.EOF:
3212 main.log.error( self.name + ": EOF exception found" )
3213 main.log.error( self.name + ": " + self.handle.before )
3214 main.cleanup()
3215 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003216 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003217 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003218 main.cleanup()
3219 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003220
acsmarsa4a4d1e2015-07-10 16:01:24 -07003221 def leaderCandidates( self, jsonFormat=True ):
3222 """
3223 Returns the output of the leaders -c command.
3224 Optional argument:
3225 * jsonFormat - boolean indicating if you want output in json
3226 """
3227 try:
3228 cmdStr = "onos:leaders -c"
3229 if jsonFormat:
3230 cmdStr += " -j"
3231 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003232 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003233 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003234 return output
Jon Hallc6793552016-01-19 14:18:37 -08003235 except AssertionError:
3236 main.log.exception( "" )
3237 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003238 except TypeError:
3239 main.log.exception( self.name + ": Object not as expected" )
3240 return None
3241 except pexpect.EOF:
3242 main.log.error( self.name + ": EOF exception found" )
3243 main.log.error( self.name + ": " + self.handle.before )
3244 main.cleanup()
3245 main.exit()
3246 except Exception:
3247 main.log.exception( self.name + ": Uncaught exception!" )
3248 main.cleanup()
3249 main.exit()
3250
Jon Hallc6793552016-01-19 14:18:37 -08003251 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003252 """
3253 Returns a list in format [leader,candidate1,candidate2,...] for a given
3254 topic parameter and an empty list if the topic doesn't exist
3255 If no leader is elected leader in the returned list will be "none"
3256 Returns None if there is a type error processing the json object
3257 """
3258 try:
Jon Hall6e709752016-02-01 13:38:46 -08003259 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003260 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003261 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003262 assert "Command not found:" not in rawOutput, rawOutput
3263 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003264 results = []
3265 for dict in output:
3266 if dict["topic"] == topic:
3267 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003268 candidates = re.split( ", ", dict["candidates"][1:-1] )
3269 results.append( leader )
3270 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003271 return results
Jon Hallc6793552016-01-19 14:18:37 -08003272 except AssertionError:
3273 main.log.exception( "" )
3274 return None
3275 except ( TypeError, ValueError ):
3276 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003277 return None
3278 except pexpect.EOF:
3279 main.log.error( self.name + ": EOF exception found" )
3280 main.log.error( self.name + ": " + self.handle.before )
3281 main.cleanup()
3282 main.exit()
3283 except Exception:
3284 main.log.exception( self.name + ": Uncaught exception!" )
3285 main.cleanup()
3286 main.exit()
3287
Jon Hall61282e32015-03-19 11:34:11 -07003288 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003289 """
3290 Returns the output of the intent Pending map.
3291 """
Jon Hall63604932015-02-26 17:09:50 -08003292 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003293 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003294 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003295 cmdStr += " -j"
3296 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003297 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003298 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003299 return output
Jon Hallc6793552016-01-19 14:18:37 -08003300 except AssertionError:
3301 main.log.exception( "" )
3302 return None
Jon Hall63604932015-02-26 17:09:50 -08003303 except TypeError:
3304 main.log.exception( self.name + ": Object not as expected" )
3305 return None
3306 except pexpect.EOF:
3307 main.log.error( self.name + ": EOF exception found" )
3308 main.log.error( self.name + ": " + self.handle.before )
3309 main.cleanup()
3310 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003311 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003312 main.log.exception( self.name + ": Uncaught exception!" )
3313 main.cleanup()
3314 main.exit()
3315
Jon Hall61282e32015-03-19 11:34:11 -07003316 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003317 """
3318 Returns the output of the raft partitions command for ONOS.
3319 """
Jon Hall61282e32015-03-19 11:34:11 -07003320 # Sample JSON
3321 # {
3322 # "leader": "tcp://10.128.30.11:7238",
3323 # "members": [
3324 # "tcp://10.128.30.11:7238",
3325 # "tcp://10.128.30.17:7238",
3326 # "tcp://10.128.30.13:7238",
3327 # ],
3328 # "name": "p1",
3329 # "term": 3
3330 # },
Jon Hall63604932015-02-26 17:09:50 -08003331 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003333 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003334 cmdStr += " -j"
3335 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003336 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003337 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003338 return output
Jon Hallc6793552016-01-19 14:18:37 -08003339 except AssertionError:
3340 main.log.exception( "" )
3341 return None
Jon Hall63604932015-02-26 17:09:50 -08003342 except TypeError:
3343 main.log.exception( self.name + ": Object not as expected" )
3344 return None
3345 except pexpect.EOF:
3346 main.log.error( self.name + ": EOF exception found" )
3347 main.log.error( self.name + ": " + self.handle.before )
3348 main.cleanup()
3349 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003350 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003351 main.log.exception( self.name + ": Uncaught exception!" )
3352 main.cleanup()
3353 main.exit()
3354
Jon Hallbe379602015-03-24 13:39:32 -07003355 def apps( self, jsonFormat=True ):
3356 """
3357 Returns the output of the apps command for ONOS. This command lists
3358 information about installed ONOS applications
3359 """
3360 # Sample JSON object
3361 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3362 # "description":"ONOS OpenFlow protocol southbound providers",
3363 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3364 # "features":"[onos-openflow]","state":"ACTIVE"}]
3365 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003366 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003367 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003368 cmdStr += " -j"
3369 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003370 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003371 assert "Command not found:" not in output, output
3372 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 return output
Jon Hallbe379602015-03-24 13:39:32 -07003374 # FIXME: look at specific exceptions/Errors
3375 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003376 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003377 return None
3378 except TypeError:
3379 main.log.exception( self.name + ": Object not as expected" )
3380 return None
3381 except pexpect.EOF:
3382 main.log.error( self.name + ": EOF exception found" )
3383 main.log.error( self.name + ": " + self.handle.before )
3384 main.cleanup()
3385 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003386 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003387 main.log.exception( self.name + ": Uncaught exception!" )
3388 main.cleanup()
3389 main.exit()
3390
Jon Hall146f1522015-03-24 15:33:24 -07003391 def appStatus( self, appName ):
3392 """
3393 Uses the onos:apps cli command to return the status of an application.
3394 Returns:
3395 "ACTIVE" - If app is installed and activated
3396 "INSTALLED" - If app is installed and deactivated
3397 "UNINSTALLED" - If app is not installed
3398 None - on error
3399 """
Jon Hall146f1522015-03-24 15:33:24 -07003400 try:
3401 if not isinstance( appName, types.StringType ):
3402 main.log.error( self.name + ".appStatus(): appName must be" +
3403 " a string" )
3404 return None
3405 output = self.apps( jsonFormat=True )
3406 appsJson = json.loads( output )
3407 state = None
3408 for app in appsJson:
3409 if appName == app.get('name'):
3410 state = app.get('state')
3411 break
3412 if state == "ACTIVE" or state == "INSTALLED":
3413 return state
3414 elif state is None:
3415 return "UNINSTALLED"
3416 elif state:
3417 main.log.error( "Unexpected state from 'onos:apps': " +
3418 str( state ) )
3419 return state
Jon Hallc6793552016-01-19 14:18:37 -08003420 except ( TypeError, ValueError ):
3421 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003422 return None
3423 except pexpect.EOF:
3424 main.log.error( self.name + ": EOF exception found" )
3425 main.log.error( self.name + ": " + self.handle.before )
3426 main.cleanup()
3427 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003428 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003429 main.log.exception( self.name + ": Uncaught exception!" )
3430 main.cleanup()
3431 main.exit()
3432
Jon Hallbe379602015-03-24 13:39:32 -07003433 def app( self, appName, option ):
3434 """
3435 Interacts with the app command for ONOS. This command manages
3436 application inventory.
3437 """
Jon Hallbe379602015-03-24 13:39:32 -07003438 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003439 # Validate argument types
3440 valid = True
3441 if not isinstance( appName, types.StringType ):
3442 main.log.error( self.name + ".app(): appName must be a " +
3443 "string" )
3444 valid = False
3445 if not isinstance( option, types.StringType ):
3446 main.log.error( self.name + ".app(): option must be a string" )
3447 valid = False
3448 if not valid:
3449 return main.FALSE
3450 # Validate Option
3451 option = option.lower()
3452 # NOTE: Install may become a valid option
3453 if option == "activate":
3454 pass
3455 elif option == "deactivate":
3456 pass
3457 elif option == "uninstall":
3458 pass
3459 else:
3460 # Invalid option
3461 main.log.error( "The ONOS app command argument only takes " +
3462 "the values: (activate|deactivate|uninstall)" +
3463 "; was given '" + option + "'")
3464 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003465 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003466 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003467 if "Error executing command" in output:
3468 main.log.error( "Error in processing onos:app command: " +
3469 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003470 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003471 elif "No such application" in output:
3472 main.log.error( "The application '" + appName +
3473 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003474 return main.FALSE
3475 elif "Command not found:" in output:
3476 main.log.error( "Error in processing onos:app command: " +
3477 str( output ) )
3478 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003479 elif "Unsupported command:" in output:
3480 main.log.error( "Incorrect command given to 'app': " +
3481 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003482 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003483 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003484 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003485 return main.TRUE
3486 except TypeError:
3487 main.log.exception( self.name + ": Object not as expected" )
3488 return main.ERROR
3489 except pexpect.EOF:
3490 main.log.error( self.name + ": EOF exception found" )
3491 main.log.error( self.name + ": " + self.handle.before )
3492 main.cleanup()
3493 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003494 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003495 main.log.exception( self.name + ": Uncaught exception!" )
3496 main.cleanup()
3497 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003498
Jon Hallbd16b922015-03-26 17:53:15 -07003499 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003500 """
3501 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003502 appName is the hierarchical app name, not the feature name
3503 If check is True, method will check the status of the app after the
3504 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003505 Returns main.TRUE if the command was successfully sent
3506 main.FALSE if the cli responded with an error or given
3507 incorrect input
3508 """
3509 try:
3510 if not isinstance( appName, types.StringType ):
3511 main.log.error( self.name + ".activateApp(): appName must be" +
3512 " a string" )
3513 return main.FALSE
3514 status = self.appStatus( appName )
3515 if status == "INSTALLED":
3516 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003517 if check and response == main.TRUE:
3518 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003519 status = self.appStatus( appName )
3520 if status == "ACTIVE":
3521 return main.TRUE
3522 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003523 main.log.debug( "The state of application " +
3524 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003525 time.sleep( 1 )
3526 return main.FALSE
3527 else: # not 'check' or command didn't succeed
3528 return response
Jon Hall146f1522015-03-24 15:33:24 -07003529 elif status == "ACTIVE":
3530 return main.TRUE
3531 elif status == "UNINSTALLED":
3532 main.log.error( self.name + ": Tried to activate the " +
3533 "application '" + appName + "' which is not " +
3534 "installed." )
3535 else:
3536 main.log.error( "Unexpected return value from appStatus: " +
3537 str( status ) )
3538 return main.ERROR
3539 except TypeError:
3540 main.log.exception( self.name + ": Object not as expected" )
3541 return main.ERROR
3542 except pexpect.EOF:
3543 main.log.error( self.name + ": EOF exception found" )
3544 main.log.error( self.name + ": " + self.handle.before )
3545 main.cleanup()
3546 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003547 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003548 main.log.exception( self.name + ": Uncaught exception!" )
3549 main.cleanup()
3550 main.exit()
3551
Jon Hallbd16b922015-03-26 17:53:15 -07003552 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003553 """
3554 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003555 appName is the hierarchical app name, not the feature name
3556 If check is True, method will check the status of the app after the
3557 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003558 Returns main.TRUE if the command was successfully sent
3559 main.FALSE if the cli responded with an error or given
3560 incorrect input
3561 """
3562 try:
3563 if not isinstance( appName, types.StringType ):
3564 main.log.error( self.name + ".deactivateApp(): appName must " +
3565 "be a string" )
3566 return main.FALSE
3567 status = self.appStatus( appName )
3568 if status == "INSTALLED":
3569 return main.TRUE
3570 elif status == "ACTIVE":
3571 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003572 if check and response == main.TRUE:
3573 for i in range(10): # try 10 times then give up
3574 status = self.appStatus( appName )
3575 if status == "INSTALLED":
3576 return main.TRUE
3577 else:
3578 time.sleep( 1 )
3579 return main.FALSE
3580 else: # not check or command didn't succeed
3581 return response
Jon Hall146f1522015-03-24 15:33:24 -07003582 elif status == "UNINSTALLED":
3583 main.log.warn( self.name + ": Tried to deactivate the " +
3584 "application '" + appName + "' which is not " +
3585 "installed." )
3586 return main.TRUE
3587 else:
3588 main.log.error( "Unexpected return value from appStatus: " +
3589 str( status ) )
3590 return main.ERROR
3591 except TypeError:
3592 main.log.exception( self.name + ": Object not as expected" )
3593 return main.ERROR
3594 except pexpect.EOF:
3595 main.log.error( self.name + ": EOF exception found" )
3596 main.log.error( self.name + ": " + self.handle.before )
3597 main.cleanup()
3598 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003599 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003600 main.log.exception( self.name + ": Uncaught exception!" )
3601 main.cleanup()
3602 main.exit()
3603
Jon Hallbd16b922015-03-26 17:53:15 -07003604 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003605 """
3606 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003607 appName is the hierarchical app name, not the feature name
3608 If check is True, method will check the status of the app after the
3609 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003610 Returns main.TRUE if the command was successfully sent
3611 main.FALSE if the cli responded with an error or given
3612 incorrect input
3613 """
3614 # TODO: check with Thomas about the state machine for apps
3615 try:
3616 if not isinstance( appName, types.StringType ):
3617 main.log.error( self.name + ".uninstallApp(): appName must " +
3618 "be a string" )
3619 return main.FALSE
3620 status = self.appStatus( appName )
3621 if status == "INSTALLED":
3622 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003623 if check and response == main.TRUE:
3624 for i in range(10): # try 10 times then give up
3625 status = self.appStatus( appName )
3626 if status == "UNINSTALLED":
3627 return main.TRUE
3628 else:
3629 time.sleep( 1 )
3630 return main.FALSE
3631 else: # not check or command didn't succeed
3632 return response
Jon Hall146f1522015-03-24 15:33:24 -07003633 elif status == "ACTIVE":
3634 main.log.warn( self.name + ": Tried to uninstall the " +
3635 "application '" + appName + "' which is " +
3636 "currently active." )
3637 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003638 if check and response == main.TRUE:
3639 for i in range(10): # try 10 times then give up
3640 status = self.appStatus( appName )
3641 if status == "UNINSTALLED":
3642 return main.TRUE
3643 else:
3644 time.sleep( 1 )
3645 return main.FALSE
3646 else: # not check or command didn't succeed
3647 return response
Jon Hall146f1522015-03-24 15:33:24 -07003648 elif status == "UNINSTALLED":
3649 return main.TRUE
3650 else:
3651 main.log.error( "Unexpected return value from appStatus: " +
3652 str( status ) )
3653 return main.ERROR
3654 except TypeError:
3655 main.log.exception( self.name + ": Object not as expected" )
3656 return main.ERROR
3657 except pexpect.EOF:
3658 main.log.error( self.name + ": EOF exception found" )
3659 main.log.error( self.name + ": " + self.handle.before )
3660 main.cleanup()
3661 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003662 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003663 main.log.exception( self.name + ": Uncaught exception!" )
3664 main.cleanup()
3665 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003666
3667 def appIDs( self, jsonFormat=True ):
3668 """
3669 Show the mappings between app id and app names given by the 'app-ids'
3670 cli command
3671 """
3672 try:
3673 cmdStr = "app-ids"
3674 if jsonFormat:
3675 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003677 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003678 assert "Command not found:" not in output, output
3679 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003680 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003681 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003682 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003683 return None
3684 except TypeError:
3685 main.log.exception( self.name + ": Object not as expected" )
3686 return None
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
3690 main.cleanup()
3691 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003692 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003693 main.log.exception( self.name + ": Uncaught exception!" )
3694 main.cleanup()
3695 main.exit()
3696
3697 def appToIDCheck( self ):
3698 """
3699 This method will check that each application's ID listed in 'apps' is
3700 the same as the ID listed in 'app-ids'. The check will also check that
3701 there are no duplicate IDs issued. Note that an app ID should be
3702 a globaly unique numerical identifier for app/app-like features. Once
3703 an ID is registered, the ID is never freed up so that if an app is
3704 reinstalled it will have the same ID.
3705
3706 Returns: main.TRUE if the check passes and
3707 main.FALSE if the check fails or
3708 main.ERROR if there is some error in processing the test
3709 """
3710 try:
Jon Hall390696c2015-05-05 17:13:41 -07003711 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003712 rawJson = self.appIDs( jsonFormat=True )
3713 if rawJson:
3714 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003715 else:
Jon Hallc6793552016-01-19 14:18:37 -08003716 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003717 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003718 rawJson = self.apps( jsonFormat=True )
3719 if rawJson:
3720 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003721 else:
Jon Hallc6793552016-01-19 14:18:37 -08003722 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003723 bail = True
3724 if bail:
3725 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003726 result = main.TRUE
3727 for app in apps:
3728 appID = app.get( 'id' )
3729 if appID is None:
3730 main.log.error( "Error parsing app: " + str( app ) )
3731 result = main.FALSE
3732 appName = app.get( 'name' )
3733 if appName is None:
3734 main.log.error( "Error parsing app: " + str( app ) )
3735 result = main.FALSE
3736 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003737 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003738 # main.log.debug( "Comparing " + str( app ) + " to " +
3739 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003740 if not current: # if ids doesn't have this id
3741 result = main.FALSE
3742 main.log.error( "'app-ids' does not have the ID for " +
3743 str( appName ) + " that apps does." )
3744 elif len( current ) > 1:
3745 # there is more than one app with this ID
3746 result = main.FALSE
3747 # We will log this later in the method
3748 elif not current[0][ 'name' ] == appName:
3749 currentName = current[0][ 'name' ]
3750 result = main.FALSE
3751 main.log.error( "'app-ids' has " + str( currentName ) +
3752 " registered under id:" + str( appID ) +
3753 " but 'apps' has " + str( appName ) )
3754 else:
3755 pass # id and name match!
3756 # now make sure that app-ids has no duplicates
3757 idsList = []
3758 namesList = []
3759 for item in ids:
3760 idsList.append( item[ 'id' ] )
3761 namesList.append( item[ 'name' ] )
3762 if len( idsList ) != len( set( idsList ) ) or\
3763 len( namesList ) != len( set( namesList ) ):
3764 main.log.error( "'app-ids' has some duplicate entries: \n"
3765 + json.dumps( ids,
3766 sort_keys=True,
3767 indent=4,
3768 separators=( ',', ': ' ) ) )
3769 result = main.FALSE
3770 return result
Jon Hallc6793552016-01-19 14:18:37 -08003771 except ( TypeError, ValueError ):
3772 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003773 return main.ERROR
3774 except pexpect.EOF:
3775 main.log.error( self.name + ": EOF exception found" )
3776 main.log.error( self.name + ": " + self.handle.before )
3777 main.cleanup()
3778 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003779 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003780 main.log.exception( self.name + ": Uncaught exception!" )
3781 main.cleanup()
3782 main.exit()
3783
Jon Hallfb760a02015-04-13 15:35:03 -07003784 def getCfg( self, component=None, propName=None, short=False,
3785 jsonFormat=True ):
3786 """
3787 Get configuration settings from onos cli
3788 Optional arguments:
3789 component - Optionally only list configurations for a specific
3790 component. If None, all components with configurations
3791 are displayed. Case Sensitive string.
3792 propName - If component is specified, propName option will show
3793 only this specific configuration from that component.
3794 Case Sensitive string.
3795 jsonFormat - Returns output as json. Note that this will override
3796 the short option
3797 short - Short, less verbose, version of configurations.
3798 This is overridden by the json option
3799 returns:
3800 Output from cli as a string or None on error
3801 """
3802 try:
3803 baseStr = "cfg"
3804 cmdStr = " get"
3805 componentStr = ""
3806 if component:
3807 componentStr += " " + component
3808 if propName:
3809 componentStr += " " + propName
3810 if jsonFormat:
3811 baseStr += " -j"
3812 elif short:
3813 baseStr += " -s"
3814 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003815 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003816 assert "Command not found:" not in output, output
3817 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003818 return output
3819 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003820 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003821 return None
3822 except TypeError:
3823 main.log.exception( self.name + ": Object not as expected" )
3824 return None
3825 except pexpect.EOF:
3826 main.log.error( self.name + ": EOF exception found" )
3827 main.log.error( self.name + ": " + self.handle.before )
3828 main.cleanup()
3829 main.exit()
3830 except Exception:
3831 main.log.exception( self.name + ": Uncaught exception!" )
3832 main.cleanup()
3833 main.exit()
3834
3835 def setCfg( self, component, propName, value=None, check=True ):
3836 """
3837 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003838 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003839 component - The case sensitive name of the component whose
3840 property is to be set
3841 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003842 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003843 value - The value to set the property to. If None, will unset the
3844 property and revert it to it's default value(if applicable)
3845 check - Boolean, Check whether the option was successfully set this
3846 only applies when a value is given.
3847 returns:
3848 main.TRUE on success or main.FALSE on failure. If check is False,
3849 will return main.TRUE unless there is an error
3850 """
3851 try:
3852 baseStr = "cfg"
3853 cmdStr = " set " + str( component ) + " " + str( propName )
3854 if value is not None:
3855 cmdStr += " " + str( value )
3856 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003857 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003858 assert "Command not found:" not in output, output
3859 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003860 if value and check:
3861 results = self.getCfg( component=str( component ),
3862 propName=str( propName ),
3863 jsonFormat=True )
3864 # Check if current value is what we just set
3865 try:
3866 jsonOutput = json.loads( results )
3867 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003868 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003869 main.log.exception( "Error parsing cfg output" )
3870 main.log.error( "output:" + repr( results ) )
3871 return main.FALSE
3872 if current == str( value ):
3873 return main.TRUE
3874 return main.FALSE
3875 return main.TRUE
3876 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003877 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003878 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003879 except ( TypeError, ValueError ):
3880 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003881 return main.FALSE
3882 except pexpect.EOF:
3883 main.log.error( self.name + ": EOF exception found" )
3884 main.log.error( self.name + ": " + self.handle.before )
3885 main.cleanup()
3886 main.exit()
3887 except Exception:
3888 main.log.exception( self.name + ": Uncaught exception!" )
3889 main.cleanup()
3890 main.exit()
3891
Jon Hall390696c2015-05-05 17:13:41 -07003892 def setTestAdd( self, setName, values ):
3893 """
3894 CLI command to add elements to a distributed set.
3895 Arguments:
3896 setName - The name of the set to add to.
3897 values - The value(s) to add to the set, space seperated.
3898 Example usages:
3899 setTestAdd( "set1", "a b c" )
3900 setTestAdd( "set2", "1" )
3901 returns:
3902 main.TRUE on success OR
3903 main.FALSE if elements were already in the set OR
3904 main.ERROR on error
3905 """
3906 try:
3907 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3908 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003909 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003910 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003911 try:
3912 # TODO: Maybe make this less hardcoded
3913 # ConsistentMap Exceptions
3914 assert "org.onosproject.store.service" not in output
3915 # Node not leader
3916 assert "java.lang.IllegalStateException" not in output
3917 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003918 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003919 "command: " + str( output ) )
3920 retryTime = 30 # Conservative time, given by Madan
3921 main.log.info( "Waiting " + str( retryTime ) +
3922 "seconds before retrying." )
3923 time.sleep( retryTime ) # Due to change in mastership
3924 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003925 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003926 assert "Error executing command" not in output
3927 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3928 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3929 main.log.info( self.name + ": " + output )
3930 if re.search( positiveMatch, output):
3931 return main.TRUE
3932 elif re.search( negativeMatch, output):
3933 return main.FALSE
3934 else:
3935 main.log.error( self.name + ": setTestAdd did not" +
3936 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003937 main.log.debug( self.name + " actual: " + repr( output ) )
3938 return main.ERROR
3939 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003940 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003941 return main.ERROR
3942 except TypeError:
3943 main.log.exception( self.name + ": Object not as expected" )
3944 return main.ERROR
3945 except pexpect.EOF:
3946 main.log.error( self.name + ": EOF exception found" )
3947 main.log.error( self.name + ": " + self.handle.before )
3948 main.cleanup()
3949 main.exit()
3950 except Exception:
3951 main.log.exception( self.name + ": Uncaught exception!" )
3952 main.cleanup()
3953 main.exit()
3954
3955 def setTestRemove( self, setName, values, clear=False, retain=False ):
3956 """
3957 CLI command to remove elements from a distributed set.
3958 Required arguments:
3959 setName - The name of the set to remove from.
3960 values - The value(s) to remove from the set, space seperated.
3961 Optional arguments:
3962 clear - Clear all elements from the set
3963 retain - Retain only the given values. (intersection of the
3964 original set and the given set)
3965 returns:
3966 main.TRUE on success OR
3967 main.FALSE if the set was not changed OR
3968 main.ERROR on error
3969 """
3970 try:
3971 cmdStr = "set-test-remove "
3972 if clear:
3973 cmdStr += "-c " + str( setName )
3974 elif retain:
3975 cmdStr += "-r " + str( setName ) + " " + str( values )
3976 else:
3977 cmdStr += str( setName ) + " " + str( values )
3978 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003979 try:
Jon Halla495f562016-05-16 18:03:26 -07003980 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003981 # TODO: Maybe make this less hardcoded
3982 # ConsistentMap Exceptions
3983 assert "org.onosproject.store.service" not in output
3984 # Node not leader
3985 assert "java.lang.IllegalStateException" not in output
3986 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003987 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003988 "command: " + str( output ) )
3989 retryTime = 30 # Conservative time, given by Madan
3990 main.log.info( "Waiting " + str( retryTime ) +
3991 "seconds before retrying." )
3992 time.sleep( retryTime ) # Due to change in mastership
3993 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003994 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003995 assert "Command not found:" not in output, output
3996 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003997 main.log.info( self.name + ": " + output )
3998 if clear:
3999 pattern = "Set " + str( setName ) + " cleared"
4000 if re.search( pattern, output ):
4001 return main.TRUE
4002 elif retain:
4003 positivePattern = str( setName ) + " was pruned to contain " +\
4004 "only elements of set \[(.*)\]"
4005 negativePattern = str( setName ) + " was not changed by " +\
4006 "retaining only elements of the set " +\
4007 "\[(.*)\]"
4008 if re.search( positivePattern, output ):
4009 return main.TRUE
4010 elif re.search( negativePattern, output ):
4011 return main.FALSE
4012 else:
4013 positivePattern = "\[(.*)\] was removed from the set " +\
4014 str( setName )
4015 if ( len( values.split() ) == 1 ):
4016 negativePattern = "\[(.*)\] was not in set " +\
4017 str( setName )
4018 else:
4019 negativePattern = "No element of \[(.*)\] was in set " +\
4020 str( setName )
4021 if re.search( positivePattern, output ):
4022 return main.TRUE
4023 elif re.search( negativePattern, output ):
4024 return main.FALSE
4025 main.log.error( self.name + ": setTestRemove did not" +
4026 " match expected output" )
4027 main.log.debug( self.name + " expected: " + pattern )
4028 main.log.debug( self.name + " actual: " + repr( output ) )
4029 return main.ERROR
4030 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004031 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004032 return main.ERROR
4033 except TypeError:
4034 main.log.exception( self.name + ": Object not as expected" )
4035 return main.ERROR
4036 except pexpect.EOF:
4037 main.log.error( self.name + ": EOF exception found" )
4038 main.log.error( self.name + ": " + self.handle.before )
4039 main.cleanup()
4040 main.exit()
4041 except Exception:
4042 main.log.exception( self.name + ": Uncaught exception!" )
4043 main.cleanup()
4044 main.exit()
4045
4046 def setTestGet( self, setName, values="" ):
4047 """
4048 CLI command to get the elements in a distributed set.
4049 Required arguments:
4050 setName - The name of the set to remove from.
4051 Optional arguments:
4052 values - The value(s) to check if in the set, space seperated.
4053 returns:
4054 main.ERROR on error OR
4055 A list of elements in the set if no optional arguments are
4056 supplied OR
4057 A tuple containing the list then:
4058 main.FALSE if the given values are not in the set OR
4059 main.TRUE if the given values are in the set OR
4060 """
4061 try:
4062 values = str( values ).strip()
4063 setName = str( setName ).strip()
4064 length = len( values.split() )
4065 containsCheck = None
4066 # Patterns to match
4067 setPattern = "\[(.*)\]"
4068 pattern = "Items in set " + setName + ":\n" + setPattern
4069 containsTrue = "Set " + setName + " contains the value " + values
4070 containsFalse = "Set " + setName + " did not contain the value " +\
4071 values
4072 containsAllTrue = "Set " + setName + " contains the the subset " +\
4073 setPattern
4074 containsAllFalse = "Set " + setName + " did not contain the the" +\
4075 " subset " + setPattern
4076
4077 cmdStr = "set-test-get "
4078 cmdStr += setName + " " + values
4079 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004080 try:
Jon Halla495f562016-05-16 18:03:26 -07004081 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004082 # TODO: Maybe make this less hardcoded
4083 # ConsistentMap Exceptions
4084 assert "org.onosproject.store.service" not in output
4085 # Node not leader
4086 assert "java.lang.IllegalStateException" not in output
4087 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004088 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004089 "command: " + str( output ) )
4090 retryTime = 30 # Conservative time, given by Madan
4091 main.log.info( "Waiting " + str( retryTime ) +
4092 "seconds before retrying." )
4093 time.sleep( retryTime ) # Due to change in mastership
4094 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004095 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004096 assert "Command not found:" not in output, output
4097 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004098 main.log.info( self.name + ": " + output )
4099
4100 if length == 0:
4101 match = re.search( pattern, output )
4102 else: # if given values
4103 if length == 1: # Contains output
4104 patternTrue = pattern + "\n" + containsTrue
4105 patternFalse = pattern + "\n" + containsFalse
4106 else: # ContainsAll output
4107 patternTrue = pattern + "\n" + containsAllTrue
4108 patternFalse = pattern + "\n" + containsAllFalse
4109 matchTrue = re.search( patternTrue, output )
4110 matchFalse = re.search( patternFalse, output )
4111 if matchTrue:
4112 containsCheck = main.TRUE
4113 match = matchTrue
4114 elif matchFalse:
4115 containsCheck = main.FALSE
4116 match = matchFalse
4117 else:
4118 main.log.error( self.name + " setTestGet did not match " +\
4119 "expected output" )
4120 main.log.debug( self.name + " expected: " + pattern )
4121 main.log.debug( self.name + " actual: " + repr( output ) )
4122 match = None
4123 if match:
4124 setMatch = match.group( 1 )
4125 if setMatch == '':
4126 setList = []
4127 else:
4128 setList = setMatch.split( ", " )
4129 if length > 0:
4130 return ( setList, containsCheck )
4131 else:
4132 return setList
4133 else: # no match
4134 main.log.error( self.name + ": setTestGet did not" +
4135 " match expected output" )
4136 main.log.debug( self.name + " expected: " + pattern )
4137 main.log.debug( self.name + " actual: " + repr( output ) )
4138 return main.ERROR
4139 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004140 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004141 return main.ERROR
4142 except TypeError:
4143 main.log.exception( self.name + ": Object not as expected" )
4144 return main.ERROR
4145 except pexpect.EOF:
4146 main.log.error( self.name + ": EOF exception found" )
4147 main.log.error( self.name + ": " + self.handle.before )
4148 main.cleanup()
4149 main.exit()
4150 except Exception:
4151 main.log.exception( self.name + ": Uncaught exception!" )
4152 main.cleanup()
4153 main.exit()
4154
4155 def setTestSize( self, setName ):
4156 """
4157 CLI command to get the elements in a distributed set.
4158 Required arguments:
4159 setName - The name of the set to remove from.
4160 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004161 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004162 None on error
4163 """
4164 try:
4165 # TODO: Should this check against the number of elements returned
4166 # and then return true/false based on that?
4167 setName = str( setName ).strip()
4168 # Patterns to match
4169 setPattern = "\[(.*)\]"
4170 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4171 setPattern
4172 cmdStr = "set-test-get -s "
4173 cmdStr += setName
4174 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004175 try:
Jon Halla495f562016-05-16 18:03:26 -07004176 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004177 # TODO: Maybe make this less hardcoded
4178 # ConsistentMap Exceptions
4179 assert "org.onosproject.store.service" not in output
4180 # Node not leader
4181 assert "java.lang.IllegalStateException" not in output
4182 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004183 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004184 "command: " + str( output ) )
4185 retryTime = 30 # Conservative time, given by Madan
4186 main.log.info( "Waiting " + str( retryTime ) +
4187 "seconds before retrying." )
4188 time.sleep( retryTime ) # Due to change in mastership
4189 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004190 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004191 assert "Command not found:" not in output, output
4192 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004193 main.log.info( self.name + ": " + output )
4194 match = re.search( pattern, output )
4195 if match:
4196 setSize = int( match.group( 1 ) )
4197 setMatch = match.group( 2 )
4198 if len( setMatch.split() ) == setSize:
4199 main.log.info( "The size returned by " + self.name +
4200 " matches the number of elements in " +
4201 "the returned set" )
4202 else:
4203 main.log.error( "The size returned by " + self.name +
4204 " does not match the number of " +
4205 "elements in the returned set." )
4206 return setSize
4207 else: # no match
4208 main.log.error( self.name + ": setTestGet did not" +
4209 " match expected output" )
4210 main.log.debug( self.name + " expected: " + pattern )
4211 main.log.debug( self.name + " actual: " + repr( output ) )
4212 return None
4213 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004214 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004215 return None
Jon Hall390696c2015-05-05 17:13:41 -07004216 except TypeError:
4217 main.log.exception( self.name + ": Object not as expected" )
4218 return None
4219 except pexpect.EOF:
4220 main.log.error( self.name + ": EOF exception found" )
4221 main.log.error( self.name + ": " + self.handle.before )
4222 main.cleanup()
4223 main.exit()
4224 except Exception:
4225 main.log.exception( self.name + ": Uncaught exception!" )
4226 main.cleanup()
4227 main.exit()
4228
Jon Hall80daded2015-05-27 16:07:00 -07004229 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004230 """
4231 Command to list the various counters in the system.
4232 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004233 if jsonFormat, a string of the json object returned by the cli
4234 command
4235 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004236 None on error
4237 """
Jon Hall390696c2015-05-05 17:13:41 -07004238 try:
4239 counters = {}
4240 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004241 if jsonFormat:
4242 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004243 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004244 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004245 assert "Command not found:" not in output, output
4246 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004247 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004248 return output
Jon Hall390696c2015-05-05 17:13:41 -07004249 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004250 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004251 return None
Jon Hall390696c2015-05-05 17:13:41 -07004252 except TypeError:
4253 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004254 return None
Jon Hall390696c2015-05-05 17:13:41 -07004255 except pexpect.EOF:
4256 main.log.error( self.name + ": EOF exception found" )
4257 main.log.error( self.name + ": " + self.handle.before )
4258 main.cleanup()
4259 main.exit()
4260 except Exception:
4261 main.log.exception( self.name + ": Uncaught exception!" )
4262 main.cleanup()
4263 main.exit()
4264
Jon Hall935db192016-04-19 00:22:04 -07004265 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004266 """
Jon Halle1a3b752015-07-22 13:02:46 -07004267 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004268 Required arguments:
4269 counter - The name of the counter to increment.
4270 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004271 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004272 returns:
4273 integer value of the counter or
4274 None on Error
4275 """
4276 try:
4277 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004278 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004279 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004280 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004281 if delta != 1:
4282 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004283 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004284 try:
Jon Halla495f562016-05-16 18:03:26 -07004285 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004286 # TODO: Maybe make this less hardcoded
4287 # ConsistentMap Exceptions
4288 assert "org.onosproject.store.service" not in output
4289 # Node not leader
4290 assert "java.lang.IllegalStateException" not in output
4291 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004292 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004293 "command: " + str( output ) )
4294 retryTime = 30 # Conservative time, given by Madan
4295 main.log.info( "Waiting " + str( retryTime ) +
4296 "seconds before retrying." )
4297 time.sleep( retryTime ) # Due to change in mastership
4298 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004299 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004300 assert "Command not found:" not in output, output
4301 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004302 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004303 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004304 match = re.search( pattern, output )
4305 if match:
4306 return int( match.group( 1 ) )
4307 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004308 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004309 " match expected output." )
4310 main.log.debug( self.name + " expected: " + pattern )
4311 main.log.debug( self.name + " actual: " + repr( output ) )
4312 return None
4313 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004314 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004315 return None
4316 except TypeError:
4317 main.log.exception( self.name + ": Object not as expected" )
4318 return None
4319 except pexpect.EOF:
4320 main.log.error( self.name + ": EOF exception found" )
4321 main.log.error( self.name + ": " + self.handle.before )
4322 main.cleanup()
4323 main.exit()
4324 except Exception:
4325 main.log.exception( self.name + ": Uncaught exception!" )
4326 main.cleanup()
4327 main.exit()
4328
Jon Hall935db192016-04-19 00:22:04 -07004329 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004330 """
4331 CLI command to get a distributed counter then add a delta to it.
4332 Required arguments:
4333 counter - The name of the counter to increment.
4334 Optional arguments:
4335 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004336 returns:
4337 integer value of the counter or
4338 None on Error
4339 """
4340 try:
4341 counter = str( counter )
4342 delta = int( delta )
4343 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004344 cmdStr += counter
4345 if delta != 1:
4346 cmdStr += " " + str( delta )
4347 output = self.sendline( cmdStr )
4348 try:
Jon Halla495f562016-05-16 18:03:26 -07004349 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004350 # TODO: Maybe make this less hardcoded
4351 # ConsistentMap Exceptions
4352 assert "org.onosproject.store.service" not in output
4353 # Node not leader
4354 assert "java.lang.IllegalStateException" not in output
4355 except AssertionError:
4356 main.log.error( "Error in processing '" + cmdStr + "' " +
4357 "command: " + str( output ) )
4358 retryTime = 30 # Conservative time, given by Madan
4359 main.log.info( "Waiting " + str( retryTime ) +
4360 "seconds before retrying." )
4361 time.sleep( retryTime ) # Due to change in mastership
4362 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004363 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004364 assert "Command not found:" not in output, output
4365 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004366 main.log.info( self.name + ": " + output )
4367 pattern = counter + " was updated to (-?\d+)"
4368 match = re.search( pattern, output )
4369 if match:
4370 return int( match.group( 1 ) )
4371 else:
4372 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4373 " match expected output." )
4374 main.log.debug( self.name + " expected: " + pattern )
4375 main.log.debug( self.name + " actual: " + repr( output ) )
4376 return None
4377 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004378 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004379 return None
4380 except TypeError:
4381 main.log.exception( self.name + ": Object not as expected" )
4382 return None
4383 except pexpect.EOF:
4384 main.log.error( self.name + ": EOF exception found" )
4385 main.log.error( self.name + ": " + self.handle.before )
4386 main.cleanup()
4387 main.exit()
4388 except Exception:
4389 main.log.exception( self.name + ": Uncaught exception!" )
4390 main.cleanup()
4391 main.exit()
4392
YPZhangfebf7302016-05-24 16:45:56 -07004393 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004394 """
4395 Description: Execute summary command in onos
4396 Returns: json object ( summary -j ), returns main.FALSE if there is
4397 no output
4398
4399 """
4400 try:
4401 cmdStr = "summary"
4402 if jsonFormat:
4403 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004404 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004405 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004406 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004407 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004408 if not handle:
4409 main.log.error( self.name + ": There is no output in " +
4410 "summary command" )
4411 return main.FALSE
4412 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004413 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004414 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004415 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004416 except TypeError:
4417 main.log.exception( self.name + ": Object not as expected" )
4418 return None
4419 except pexpect.EOF:
4420 main.log.error( self.name + ": EOF exception found" )
4421 main.log.error( self.name + ": " + self.handle.before )
4422 main.cleanup()
4423 main.exit()
4424 except Exception:
4425 main.log.exception( self.name + ": Uncaught exception!" )
4426 main.cleanup()
4427 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004428
Jon Hall935db192016-04-19 00:22:04 -07004429 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004430 """
4431 CLI command to get the value of a key in a consistent map using
4432 transactions. This a test function and can only get keys from the
4433 test map hard coded into the cli command
4434 Required arguments:
4435 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004436 returns:
4437 The string value of the key or
4438 None on Error
4439 """
4440 try:
4441 keyName = str( keyName )
4442 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004443 cmdStr += keyName
4444 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004445 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004446 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004447 try:
4448 # TODO: Maybe make this less hardcoded
4449 # ConsistentMap Exceptions
4450 assert "org.onosproject.store.service" not in output
4451 # Node not leader
4452 assert "java.lang.IllegalStateException" not in output
4453 except AssertionError:
4454 main.log.error( "Error in processing '" + cmdStr + "' " +
4455 "command: " + str( output ) )
4456 return None
4457 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4458 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004459 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004460 return None
4461 else:
4462 match = re.search( pattern, output )
4463 if match:
4464 return match.groupdict()[ 'value' ]
4465 else:
4466 main.log.error( self.name + ": transactionlMapGet did not" +
4467 " match expected output." )
4468 main.log.debug( self.name + " expected: " + pattern )
4469 main.log.debug( self.name + " actual: " + repr( output ) )
4470 return None
Jon Hallc6793552016-01-19 14:18:37 -08004471 except AssertionError:
4472 main.log.exception( "" )
4473 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004474 except TypeError:
4475 main.log.exception( self.name + ": Object not as expected" )
4476 return None
4477 except pexpect.EOF:
4478 main.log.error( self.name + ": EOF exception found" )
4479 main.log.error( self.name + ": " + self.handle.before )
4480 main.cleanup()
4481 main.exit()
4482 except Exception:
4483 main.log.exception( self.name + ": Uncaught exception!" )
4484 main.cleanup()
4485 main.exit()
4486
Jon Hall935db192016-04-19 00:22:04 -07004487 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004488 """
4489 CLI command to put a value into 'numKeys' number of keys in a
4490 consistent map using transactions. This a test function and can only
4491 put into keys named 'Key#' of the test map hard coded into the cli command
4492 Required arguments:
4493 numKeys - Number of keys to add the value to
4494 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004495 returns:
4496 A dictionary whose keys are the name of the keys put into the map
4497 and the values of the keys are dictionaries whose key-values are
4498 'value': value put into map and optionaly
4499 'oldValue': Previous value in the key or
4500 None on Error
4501
4502 Example output
4503 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4504 'Key2': {'value': 'Testing'} }
4505 """
4506 try:
4507 numKeys = str( numKeys )
4508 value = str( value )
4509 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004510 cmdStr += numKeys + " " + value
4511 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004512 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004513 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004514 try:
4515 # TODO: Maybe make this less hardcoded
4516 # ConsistentMap Exceptions
4517 assert "org.onosproject.store.service" not in output
4518 # Node not leader
4519 assert "java.lang.IllegalStateException" not in output
4520 except AssertionError:
4521 main.log.error( "Error in processing '" + cmdStr + "' " +
4522 "command: " + str( output ) )
4523 return None
4524 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4525 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4526 results = {}
4527 for line in output.splitlines():
4528 new = re.search( newPattern, line )
4529 updated = re.search( updatedPattern, line )
4530 if new:
4531 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4532 elif updated:
4533 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004534 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004535 else:
4536 main.log.error( self.name + ": transactionlMapGet did not" +
4537 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004538 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4539 newPattern,
4540 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004541 main.log.debug( self.name + " actual: " + repr( output ) )
4542 return results
Jon Hallc6793552016-01-19 14:18:37 -08004543 except AssertionError:
4544 main.log.exception( "" )
4545 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004546 except TypeError:
4547 main.log.exception( self.name + ": Object not as expected" )
4548 return None
4549 except pexpect.EOF:
4550 main.log.error( self.name + ": EOF exception found" )
4551 main.log.error( self.name + ": " + self.handle.before )
4552 main.cleanup()
4553 main.exit()
4554 except Exception:
4555 main.log.exception( self.name + ": Uncaught exception!" )
4556 main.cleanup()
4557 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004558
acsmarsdaea66c2015-09-03 11:44:06 -07004559 def maps( self, jsonFormat=True ):
4560 """
4561 Description: Returns result of onos:maps
4562 Optional:
4563 * jsonFormat: enable json formatting of output
4564 """
4565 try:
4566 cmdStr = "maps"
4567 if jsonFormat:
4568 cmdStr += " -j"
4569 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004570 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004571 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004572 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004573 except AssertionError:
4574 main.log.exception( "" )
4575 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004576 except TypeError:
4577 main.log.exception( self.name + ": Object not as expected" )
4578 return None
4579 except pexpect.EOF:
4580 main.log.error( self.name + ": EOF exception found" )
4581 main.log.error( self.name + ": " + self.handle.before )
4582 main.cleanup()
4583 main.exit()
4584 except Exception:
4585 main.log.exception( self.name + ": Uncaught exception!" )
4586 main.cleanup()
4587 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004588
4589 def getSwController( self, uri, jsonFormat=True ):
4590 """
4591 Descrition: Gets the controller information from the device
4592 """
4593 try:
4594 cmd = "device-controllers "
4595 if jsonFormat:
4596 cmd += "-j "
4597 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004598 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004599 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004600 return response
Jon Hallc6793552016-01-19 14:18:37 -08004601 except AssertionError:
4602 main.log.exception( "" )
4603 return None
GlennRC050596c2015-11-18 17:06:41 -08004604 except TypeError:
4605 main.log.exception( self.name + ": Object not as expected" )
4606 return None
4607 except pexpect.EOF:
4608 main.log.error( self.name + ": EOF exception found" )
4609 main.log.error( self.name + ": " + self.handle.before )
4610 main.cleanup()
4611 main.exit()
4612 except Exception:
4613 main.log.exception( self.name + ": Uncaught exception!" )
4614 main.cleanup()
4615 main.exit()
4616
4617 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4618 """
4619 Descrition: sets the controller(s) for the specified device
4620
4621 Parameters:
4622 Required: uri - String: The uri of the device(switch).
4623 ip - String or List: The ip address of the controller.
4624 This parameter can be formed in a couple of different ways.
4625 VALID:
4626 10.0.0.1 - just the ip address
4627 tcp:10.0.0.1 - the protocol and the ip address
4628 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4629 so that you can add controllers with different
4630 protocols and ports
4631 INVALID:
4632 10.0.0.1:6653 - this is not supported by ONOS
4633
4634 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4635 port - The port number.
4636 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4637
4638 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4639 """
4640 try:
4641 cmd = "device-setcontrollers"
4642
4643 if jsonFormat:
4644 cmd += " -j"
4645 cmd += " " + uri
4646 if isinstance( ip, str ):
4647 ip = [ip]
4648 for item in ip:
4649 if ":" in item:
4650 sitem = item.split( ":" )
4651 if len(sitem) == 3:
4652 cmd += " " + item
4653 elif "." in sitem[1]:
4654 cmd += " {}:{}".format(item, port)
4655 else:
4656 main.log.error( "Malformed entry: " + item )
4657 raise TypeError
4658 else:
4659 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004660 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004661 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004662 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004663 if "Error" in response:
4664 main.log.error( response )
4665 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004666 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004667 except AssertionError:
4668 main.log.exception( "" )
4669 return None
GlennRC050596c2015-11-18 17:06:41 -08004670 except TypeError:
4671 main.log.exception( self.name + ": Object not as expected" )
4672 return main.FALSE
4673 except pexpect.EOF:
4674 main.log.error( self.name + ": EOF exception found" )
4675 main.log.error( self.name + ": " + self.handle.before )
4676 main.cleanup()
4677 main.exit()
4678 except Exception:
4679 main.log.exception( self.name + ": Uncaught exception!" )
4680 main.cleanup()
4681 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004682
4683 def removeDevice( self, device ):
4684 '''
4685 Description:
4686 Remove a device from ONOS by passing the uri of the device(s).
4687 Parameters:
4688 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4689 Returns:
4690 Returns main.FALSE if an exception is thrown or an error is present
4691 in the response. Otherwise, returns main.TRUE.
4692 NOTE:
4693 If a host cannot be removed, then this function will return main.FALSE
4694 '''
4695 try:
4696 if type( device ) is str:
4697 device = list( device )
4698
4699 for d in device:
4700 time.sleep( 1 )
4701 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004702 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004703 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004704 if "Error" in response:
4705 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4706 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004707 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004708 except AssertionError:
4709 main.log.exception( "" )
4710 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004711 except TypeError:
4712 main.log.exception( self.name + ": Object not as expected" )
4713 return main.FALSE
4714 except pexpect.EOF:
4715 main.log.error( self.name + ": EOF exception found" )
4716 main.log.error( self.name + ": " + self.handle.before )
4717 main.cleanup()
4718 main.exit()
4719 except Exception:
4720 main.log.exception( self.name + ": Uncaught exception!" )
4721 main.cleanup()
4722 main.exit()
4723
4724 def removeHost( self, host ):
4725 '''
4726 Description:
4727 Remove a host from ONOS by passing the id of the host(s)
4728 Parameters:
4729 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4730 Returns:
4731 Returns main.FALSE if an exception is thrown or an error is present
4732 in the response. Otherwise, returns main.TRUE.
4733 NOTE:
4734 If a host cannot be removed, then this function will return main.FALSE
4735 '''
4736 try:
4737 if type( host ) is str:
4738 host = list( host )
4739
4740 for h in host:
4741 time.sleep( 1 )
4742 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004743 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004744 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004745 if "Error" in response:
4746 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4747 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004748 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004749 except AssertionError:
4750 main.log.exception( "" )
4751 return None
GlennRC20fc6522015-12-23 23:26:57 -08004752 except TypeError:
4753 main.log.exception( self.name + ": Object not as expected" )
4754 return main.FALSE
4755 except pexpect.EOF:
4756 main.log.error( self.name + ": EOF exception found" )
4757 main.log.error( self.name + ": " + self.handle.before )
4758 main.cleanup()
4759 main.exit()
4760 except Exception:
4761 main.log.exception( self.name + ": Uncaught exception!" )
4762 main.cleanup()
4763 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004764
YPZhangfebf7302016-05-24 16:45:56 -07004765 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004766 '''
4767 Description:
4768 Bring link down or up in the null-provider.
4769 params:
4770 begin - (string) One end of a device or switch.
4771 end - (string) the other end of the device or switch
4772 returns:
4773 main.TRUE if no exceptions were thrown and no Errors are
4774 present in the resoponse. Otherwise, returns main.FALSE
4775 '''
4776 try:
Jon Hallc6793552016-01-19 14:18:37 -08004777 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004778 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004779 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004780 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004781 if "Error" in response or "Failure" in response:
4782 main.log.error( response )
4783 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004784 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004785 except AssertionError:
4786 main.log.exception( "" )
4787 return None
GlennRCed771242016-01-13 17:02:47 -08004788 except TypeError:
4789 main.log.exception( self.name + ": Object not as expected" )
4790 return main.FALSE
4791 except pexpect.EOF:
4792 main.log.error( self.name + ": EOF exception found" )
4793 main.log.error( self.name + ": " + self.handle.before )
4794 main.cleanup()
4795 main.exit()
4796 except Exception:
4797 main.log.exception( self.name + ": Uncaught exception!" )
4798 main.cleanup()
4799 main.exit()
4800
Flavio Castro82ee2f62016-06-07 15:04:12 -07004801 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4802 '''
4803 Description:
4804 Changes the state of port in an OF switch by means of the
4805 PORTSTATUS OF messages.
4806 params:
4807 dpid - (string) Datapath ID of the device
4808 port - (string) target port in the device
4809 state - (string) target state (enable or disabled)
4810 returns:
4811 main.TRUE if no exceptions were thrown and no Errors are
4812 present in the resoponse. Otherwise, returns main.FALSE
4813 '''
4814 try:
4815 cmd = "portstate {} {} {}".format( dpid, port, state )
4816 response = self.sendline( cmd, showResponse=True )
4817 assert response is not None, "Error in sendline"
4818 assert "Command not found:" not in response, response
4819 if "Error" in response or "Failure" in response:
4820 main.log.error( response )
4821 return main.FALSE
4822 return main.TRUE
4823 except AssertionError:
4824 main.log.exception( "" )
4825 return None
4826 except TypeError:
4827 main.log.exception( self.name + ": Object not as expected" )
4828 return main.FALSE
4829 except pexpect.EOF:
4830 main.log.error( self.name + ": EOF exception found" )
4831 main.log.error( self.name + ": " + self.handle.before )
4832 main.cleanup()
4833 main.exit()
4834 except Exception:
4835 main.log.exception( self.name + ": Uncaught exception!" )
4836 main.cleanup()
4837 main.exit()
4838
4839 def logSet( self, level="INFO", app="org.onosproject" ):
4840 """
4841 Set the logging level to lvl for a specific app
4842 returns main.TRUE on success
4843 returns main.FALSE if Error occurred
4844 if noExit is True, TestON will not exit, but clean up
4845 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4846 Level defaults to INFO
4847 """
4848 try:
4849 self.handle.sendline( "log:set %s %s" %( level, app ) )
4850 self.handle.expect( "onos>" )
4851
4852 response = self.handle.before
4853 if re.search( "Error", response ):
4854 return main.FALSE
4855 return main.TRUE
4856 except pexpect.TIMEOUT:
4857 main.log.exception( self.name + ": TIMEOUT exception found" )
4858 main.cleanup()
4859 main.exit()
4860 except pexpect.EOF:
4861 main.log.error( self.name + ": EOF exception found" )
4862 main.log.error( self.name + ": " + self.handle.before )
4863 main.cleanup()
4864 main.exit()
4865 except Exception:
4866 main.log.exception( self.name + ": Uncaught exception!" )
4867 main.cleanup()
4868 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004869
4870 def getGraphDict( self, timeout=60, includeHost=False ):
4871 """
4872 Return a dictionary which describes the latest network topology data as a
4873 graph.
4874 An example of the dictionary:
4875 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4876 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4877 Each vertex should at least have an 'edges' attribute which describes the
4878 adjacency information. The value of 'edges' attribute is also represented by
4879 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4880 list of attributes.
4881 An example of the edges dictionary:
4882 'edges': { vertex2: { 'port': ..., 'weight': ... },
4883 vertex3: { 'port': ..., 'weight': ... } }
4884 If includeHost == True, all hosts (and host-switch links) will be included
4885 in topology data.
4886 """
4887 graphDict = {}
4888 try:
4889 links = self.links()
4890 links = json.loads( links )
4891 devices = self.devices()
4892 devices = json.loads( devices )
4893 idToDevice = {}
4894 for device in devices:
4895 idToDevice[ device[ 'id' ] ] = device
4896 if includeHost:
4897 hosts = self.hosts()
4898 # FIXME: support 'includeHost' argument
4899 for link in links:
4900 nodeA = link[ 'src' ][ 'device' ]
4901 nodeB = link[ 'dst' ][ 'device' ]
4902 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4903 if not nodeA in graphDict.keys():
4904 graphDict[ nodeA ] = { 'edges':{},
4905 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4906 'type':idToDevice[ nodeA ][ 'type' ],
4907 'available':idToDevice[ nodeA ][ 'available' ],
4908 'role':idToDevice[ nodeA ][ 'role' ],
4909 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4910 'hw':idToDevice[ nodeA ][ 'hw' ],
4911 'sw':idToDevice[ nodeA ][ 'sw' ],
4912 'serial':idToDevice[ nodeA ][ 'serial' ],
4913 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4914 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4915 else:
4916 # Assert nodeB is not connected to any current links of nodeA
4917 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4918 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4919 'type':link[ 'type' ],
4920 'state':link[ 'state' ] }
4921 return graphDict
4922 except ( TypeError, ValueError ):
4923 main.log.exception( self.name + ": Object not as expected" )
4924 return None
4925 except KeyError:
4926 main.log.exception( self.name + ": KeyError exception found" )
4927 return None
4928 except AssertionError:
4929 main.log.exception( self.name + ": AssertionError exception found" )
4930 return None
4931 except pexpect.EOF:
4932 main.log.error( self.name + ": EOF exception found" )
4933 main.log.error( self.name + ": " + self.handle.before )
4934 return None
4935 except Exception:
4936 main.log.exception( self.name + ": Uncaught exception!" )
4937 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004938
4939 def getIntentPerfSummary( self ):
4940 '''
4941 Send command to check intent-perf summary
4942 Returns: dictionary for intent-perf summary
4943 if something wrong, function will return None
4944 '''
4945 cmd = "intent-perf -s"
4946 respDic = {}
4947 resp = self.sendline( cmd )
4948 try:
4949 # Generate the dictionary to return
4950 for l in resp.split( "\n" ):
4951 # Delete any white space in line
4952 temp = re.sub( r'\s+', '', l )
4953 temp = temp.split( ":" )
4954 respDic[ temp[0] ] = temp[ 1 ]
4955
4956 except (TypeError, ValueError):
4957 main.log.exception( self.name + ": Object not as expected" )
4958 return None
4959 except KeyError:
4960 main.log.exception( self.name + ": KeyError exception found" )
4961 return None
4962 except AssertionError:
4963 main.log.exception( self.name + ": AssertionError exception found" )
4964 return None
4965 except pexpect.EOF:
4966 main.log.error( self.name + ": EOF exception found" )
4967 main.log.error( self.name + ": " + self.handle.before )
4968 return None
4969 except Exception:
4970 main.log.exception( self.name + ": Uncaught exception!" )
4971 return None
4972 return respDic
4973
4974