blob: 9f4dd29efda9b4a2fba3db470d819741507de413 [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:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002817 topology = self.getTopology( self.topology() )
2818 summary = json.loads( self.summary() )
Jon Hall97cf84a2016-06-20 13:35:58 -07002819
Flavio Castro82ee2f62016-06-07 15:04:12 -07002820 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002821 return main.ERROR
2822 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002823 # Is the number of switches is what we expected
2824 devices = topology.get( 'devices', False )
2825 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002826 nodes = summary.get( 'nodes', False )
2827 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002828 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002830 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002832 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2833 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002834 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002835 output = output + "The number of links and switches match "\
2836 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002837 result = main.TRUE
2838 else:
You Wang24139872016-05-03 11:48:47 -07002839 output = output + \
2840 "The number of links and switches does not match " + \
2841 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002842 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002843 output = output + "\n ONOS sees %i devices" % int( devices )
2844 output = output + " (%i expected) " % int( numoswitch )
2845 output = output + "and %i links " % int( links )
2846 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002847 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002848 output = output + "and %i controllers " % int( nodes )
2849 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002850 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002851 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002852 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002853 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002854 else:
You Wang24139872016-05-03 11:48:47 -07002855 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002856 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002857 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002858 main.log.error( self.name + ": EOF exception found" )
2859 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002860 main.cleanup()
2861 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002862 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002863 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002864 main.cleanup()
2865 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002866
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002868 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002869 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002870 deviceId must be the id of a device as seen in the onos devices command
2871 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002872 role must be either master, standby, or none
2873
Jon Halle3f39ff2015-01-13 11:50:53 -08002874 Returns:
2875 main.TRUE or main.FALSE based on argument verification and
2876 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002877 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002878 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002879 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002880 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002881 cmdStr = "device-role " +\
2882 str( deviceId ) + " " +\
2883 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002884 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002886 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002887 if re.search( "Error", handle ):
2888 # end color output to escape any colours
2889 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002890 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002891 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002892 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002893 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002894 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 main.log.error( "Invalid 'role' given to device_role(). " +
2896 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002897 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002898 except AssertionError:
2899 main.log.exception( "" )
2900 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002901 except TypeError:
2902 main.log.exception( self.name + ": Object not as expected" )
2903 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002904 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002905 main.log.error( self.name + ": EOF exception found" )
2906 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002907 main.cleanup()
2908 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002909 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002910 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002911 main.cleanup()
2912 main.exit()
2913
kelvin-onlabd3b64892015-01-20 13:26:24 -08002914 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002915 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002916 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002917 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002919 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002920 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002921 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002923 cmdStr += " -j"
2924 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002925 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002927 except AssertionError:
2928 main.log.exception( "" )
2929 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002930 except TypeError:
2931 main.log.exception( self.name + ": Object not as expected" )
2932 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002934 main.log.error( self.name + ": EOF exception found" )
2935 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002936 main.cleanup()
2937 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002938 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002939 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002940 main.cleanup()
2941 main.exit()
2942
kelvin-onlabd3b64892015-01-20 13:26:24 -08002943 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002944 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002945 CLI command to get the current leader for the Election test application
2946 NOTE: Requires installation of the onos-app-election feature
2947 Returns: Node IP of the leader if one exists
2948 None if none exists
2949 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002950 """
Jon Hall94fd0472014-12-08 11:52:42 -08002951 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002952 cmdStr = "election-test-leader"
2953 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002954 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002955 # Leader
2956 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002957 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002958 nodeSearch = re.search( leaderPattern, response )
2959 if nodeSearch:
2960 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002961 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002962 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002963 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002964 # no leader
2965 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002966 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002967 nullSearch = re.search( nullPattern, response )
2968 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002969 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002970 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002971 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002972 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07002973 main.log.error( "Error in electionTestLeader on " + self.name +
2974 ": " + "unexpected response" )
2975 main.log.error( repr( response ) )
2976 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002977 except AssertionError:
2978 main.log.exception( "" )
2979 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002980 except TypeError:
2981 main.log.exception( self.name + ": Object not as expected" )
2982 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002984 main.log.error( self.name + ": EOF exception found" )
2985 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002986 main.cleanup()
2987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002989 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002990 main.cleanup()
2991 main.exit()
2992
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002995 CLI command to run for leadership of the Election test application.
2996 NOTE: Requires installation of the onos-app-election feature
2997 Returns: Main.TRUE on success
2998 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002999 """
Jon Hall94fd0472014-12-08 11:52:42 -08003000 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003001 cmdStr = "election-test-run"
3002 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003003 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003004 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003006 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003007 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003008 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003009 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003010 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003011 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003012 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003013 main.log.error( "Error in electionTestRun on " + self.name +
3014 ": " + "unexpected response" )
3015 main.log.error( repr( response ) )
3016 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003017 except AssertionError:
3018 main.log.exception( "" )
3019 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003020 except TypeError:
3021 main.log.exception( self.name + ": Object not as expected" )
3022 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003024 main.log.error( self.name + ": EOF exception found" )
3025 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003026 main.cleanup()
3027 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003028 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003029 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003030 main.cleanup()
3031 main.exit()
3032
kelvin-onlabd3b64892015-01-20 13:26:24 -08003033 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003034 """
Jon Hall94fd0472014-12-08 11:52:42 -08003035 * CLI command to withdraw the local node from leadership election for
3036 * the Election test application.
3037 #NOTE: Requires installation of the onos-app-election feature
3038 Returns: Main.TRUE on success
3039 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003040 """
Jon Hall94fd0472014-12-08 11:52:42 -08003041 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003042 cmdStr = "election-test-withdraw"
3043 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003044 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003045 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003046 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003048 if re.search( successPattern, response ):
3049 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003050 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003051 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003052 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003053 main.log.error( "Error in electionTestWithdraw on " +
3054 self.name + ": " + "unexpected response" )
3055 main.log.error( repr( response ) )
3056 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003057 except AssertionError:
3058 main.log.exception( "" )
3059 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003060 except TypeError:
3061 main.log.exception( self.name + ": Object not as expected" )
3062 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003063 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003064 main.log.error( self.name + ": EOF exception found" )
3065 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003066 main.cleanup()
3067 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003068 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003069 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003070 main.cleanup()
3071 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003072
kelvin8ec71442015-01-15 16:57:00 -08003073 def getDevicePortsEnabledCount( self, dpid ):
3074 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003075 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003076 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003077 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003078 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003079 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3080 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003081 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003082 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003083 if re.search( "No such device", output ):
3084 main.log.error( "Error in getting ports" )
3085 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003086 return output
Jon Hallc6793552016-01-19 14:18:37 -08003087 except AssertionError:
3088 main.log.exception( "" )
3089 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003090 except TypeError:
3091 main.log.exception( self.name + ": Object not as expected" )
3092 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003094 main.log.error( self.name + ": EOF exception found" )
3095 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003096 main.cleanup()
3097 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003099 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003100 main.cleanup()
3101 main.exit()
3102
kelvin8ec71442015-01-15 16:57:00 -08003103 def getDeviceLinksActiveCount( self, dpid ):
3104 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003105 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003106 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003107 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003108 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3110 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003111 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003112 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003113 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003114 main.log.error( "Error in getting ports " )
3115 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003116 return output
Jon Hallc6793552016-01-19 14:18:37 -08003117 except AssertionError:
3118 main.log.exception( "" )
3119 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003120 except TypeError:
3121 main.log.exception( self.name + ": Object not as expected" )
3122 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003124 main.log.error( self.name + ": EOF exception found" )
3125 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003126 main.cleanup()
3127 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003128 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003129 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 main.cleanup()
3131 main.exit()
3132
kelvin8ec71442015-01-15 16:57:00 -08003133 def getAllIntentIds( self ):
3134 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003135 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003136 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003138 cmdStr = "onos:intents | grep id="
3139 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003140 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003141 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 if re.search( "Error", output ):
3143 main.log.error( "Error in getting ports" )
3144 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003145 return output
Jon Hallc6793552016-01-19 14:18:37 -08003146 except AssertionError:
3147 main.log.exception( "" )
3148 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003149 except TypeError:
3150 main.log.exception( self.name + ": Object not as expected" )
3151 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003153 main.log.error( self.name + ": EOF exception found" )
3154 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003155 main.cleanup()
3156 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003158 main.log.exception( self.name + ": Uncaught exception!" )
3159 main.cleanup()
3160 main.exit()
3161
Jon Hall73509952015-02-24 16:42:56 -08003162 def intentSummary( self ):
3163 """
Jon Hallefbd9792015-03-05 16:11:36 -08003164 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003165 """
3166 try:
3167 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003168 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003169 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003170 states.append( intent.get( 'state', None ) )
3171 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003172 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003173 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003174 except ( TypeError, ValueError ):
3175 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003176 return None
3177 except pexpect.EOF:
3178 main.log.error( self.name + ": EOF exception found" )
3179 main.log.error( self.name + ": " + self.handle.before )
3180 main.cleanup()
3181 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003182 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003183 main.log.exception( self.name + ": Uncaught exception!" )
3184 main.cleanup()
3185 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003186
Jon Hall61282e32015-03-19 11:34:11 -07003187 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003188 """
3189 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003190 Optional argument:
3191 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003192 """
Jon Hall63604932015-02-26 17:09:50 -08003193 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003194 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003195 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003196 cmdStr += " -j"
3197 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003198 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003199 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003200 return output
Jon Hallc6793552016-01-19 14:18:37 -08003201 except AssertionError:
3202 main.log.exception( "" )
3203 return None
Jon Hall63604932015-02-26 17:09:50 -08003204 except TypeError:
3205 main.log.exception( self.name + ": Object not as expected" )
3206 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003207 except pexpect.EOF:
3208 main.log.error( self.name + ": EOF exception found" )
3209 main.log.error( self.name + ": " + self.handle.before )
3210 main.cleanup()
3211 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003212 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003213 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003214 main.cleanup()
3215 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003216
acsmarsa4a4d1e2015-07-10 16:01:24 -07003217 def leaderCandidates( self, jsonFormat=True ):
3218 """
3219 Returns the output of the leaders -c command.
3220 Optional argument:
3221 * jsonFormat - boolean indicating if you want output in json
3222 """
3223 try:
3224 cmdStr = "onos:leaders -c"
3225 if jsonFormat:
3226 cmdStr += " -j"
3227 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003228 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003229 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003230 return output
Jon Hallc6793552016-01-19 14:18:37 -08003231 except AssertionError:
3232 main.log.exception( "" )
3233 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003234 except TypeError:
3235 main.log.exception( self.name + ": Object not as expected" )
3236 return None
3237 except pexpect.EOF:
3238 main.log.error( self.name + ": EOF exception found" )
3239 main.log.error( self.name + ": " + self.handle.before )
3240 main.cleanup()
3241 main.exit()
3242 except Exception:
3243 main.log.exception( self.name + ": Uncaught exception!" )
3244 main.cleanup()
3245 main.exit()
3246
Jon Hallc6793552016-01-19 14:18:37 -08003247 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003248 """
3249 Returns a list in format [leader,candidate1,candidate2,...] for a given
3250 topic parameter and an empty list if the topic doesn't exist
3251 If no leader is elected leader in the returned list will be "none"
3252 Returns None if there is a type error processing the json object
3253 """
3254 try:
Jon Hall6e709752016-02-01 13:38:46 -08003255 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003256 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003257 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003258 assert "Command not found:" not in rawOutput, rawOutput
3259 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003260 results = []
3261 for dict in output:
3262 if dict["topic"] == topic:
3263 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003264 candidates = re.split( ", ", dict["candidates"][1:-1] )
3265 results.append( leader )
3266 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003267 return results
Jon Hallc6793552016-01-19 14:18:37 -08003268 except AssertionError:
3269 main.log.exception( "" )
3270 return None
3271 except ( TypeError, ValueError ):
3272 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003273 return None
3274 except pexpect.EOF:
3275 main.log.error( self.name + ": EOF exception found" )
3276 main.log.error( self.name + ": " + self.handle.before )
3277 main.cleanup()
3278 main.exit()
3279 except Exception:
3280 main.log.exception( self.name + ": Uncaught exception!" )
3281 main.cleanup()
3282 main.exit()
3283
Jon Hall61282e32015-03-19 11:34:11 -07003284 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003285 """
3286 Returns the output of the intent Pending map.
3287 """
Jon Hall63604932015-02-26 17:09:50 -08003288 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003289 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003290 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003291 cmdStr += " -j"
3292 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003293 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003294 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003295 return output
Jon Hallc6793552016-01-19 14:18:37 -08003296 except AssertionError:
3297 main.log.exception( "" )
3298 return None
Jon Hall63604932015-02-26 17:09:50 -08003299 except TypeError:
3300 main.log.exception( self.name + ": Object not as expected" )
3301 return None
3302 except pexpect.EOF:
3303 main.log.error( self.name + ": EOF exception found" )
3304 main.log.error( self.name + ": " + self.handle.before )
3305 main.cleanup()
3306 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003307 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003308 main.log.exception( self.name + ": Uncaught exception!" )
3309 main.cleanup()
3310 main.exit()
3311
Jon Hall61282e32015-03-19 11:34:11 -07003312 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003313 """
3314 Returns the output of the raft partitions command for ONOS.
3315 """
Jon Hall61282e32015-03-19 11:34:11 -07003316 # Sample JSON
3317 # {
3318 # "leader": "tcp://10.128.30.11:7238",
3319 # "members": [
3320 # "tcp://10.128.30.11:7238",
3321 # "tcp://10.128.30.17:7238",
3322 # "tcp://10.128.30.13:7238",
3323 # ],
3324 # "name": "p1",
3325 # "term": 3
3326 # },
Jon Hall63604932015-02-26 17:09:50 -08003327 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003328 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003329 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003330 cmdStr += " -j"
3331 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003332 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003333 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003334 return output
Jon Hallc6793552016-01-19 14:18:37 -08003335 except AssertionError:
3336 main.log.exception( "" )
3337 return None
Jon Hall63604932015-02-26 17:09:50 -08003338 except TypeError:
3339 main.log.exception( self.name + ": Object not as expected" )
3340 return None
3341 except pexpect.EOF:
3342 main.log.error( self.name + ": EOF exception found" )
3343 main.log.error( self.name + ": " + self.handle.before )
3344 main.cleanup()
3345 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003346 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003347 main.log.exception( self.name + ": Uncaught exception!" )
3348 main.cleanup()
3349 main.exit()
3350
Jon Hallbe379602015-03-24 13:39:32 -07003351 def apps( self, jsonFormat=True ):
3352 """
3353 Returns the output of the apps command for ONOS. This command lists
3354 information about installed ONOS applications
3355 """
3356 # Sample JSON object
3357 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3358 # "description":"ONOS OpenFlow protocol southbound providers",
3359 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3360 # "features":"[onos-openflow]","state":"ACTIVE"}]
3361 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003362 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003363 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003364 cmdStr += " -j"
3365 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003366 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003367 assert "Command not found:" not in output, output
3368 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003369 return output
Jon Hallbe379602015-03-24 13:39:32 -07003370 # FIXME: look at specific exceptions/Errors
3371 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003372 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003373 return None
3374 except TypeError:
3375 main.log.exception( self.name + ": Object not as expected" )
3376 return None
3377 except pexpect.EOF:
3378 main.log.error( self.name + ": EOF exception found" )
3379 main.log.error( self.name + ": " + self.handle.before )
3380 main.cleanup()
3381 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003382 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003383 main.log.exception( self.name + ": Uncaught exception!" )
3384 main.cleanup()
3385 main.exit()
3386
Jon Hall146f1522015-03-24 15:33:24 -07003387 def appStatus( self, appName ):
3388 """
3389 Uses the onos:apps cli command to return the status of an application.
3390 Returns:
3391 "ACTIVE" - If app is installed and activated
3392 "INSTALLED" - If app is installed and deactivated
3393 "UNINSTALLED" - If app is not installed
3394 None - on error
3395 """
Jon Hall146f1522015-03-24 15:33:24 -07003396 try:
3397 if not isinstance( appName, types.StringType ):
3398 main.log.error( self.name + ".appStatus(): appName must be" +
3399 " a string" )
3400 return None
3401 output = self.apps( jsonFormat=True )
3402 appsJson = json.loads( output )
3403 state = None
3404 for app in appsJson:
3405 if appName == app.get('name'):
3406 state = app.get('state')
3407 break
3408 if state == "ACTIVE" or state == "INSTALLED":
3409 return state
3410 elif state is None:
3411 return "UNINSTALLED"
3412 elif state:
3413 main.log.error( "Unexpected state from 'onos:apps': " +
3414 str( state ) )
3415 return state
Jon Hallc6793552016-01-19 14:18:37 -08003416 except ( TypeError, ValueError ):
3417 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003418 return None
3419 except pexpect.EOF:
3420 main.log.error( self.name + ": EOF exception found" )
3421 main.log.error( self.name + ": " + self.handle.before )
3422 main.cleanup()
3423 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003424 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003425 main.log.exception( self.name + ": Uncaught exception!" )
3426 main.cleanup()
3427 main.exit()
3428
Jon Hallbe379602015-03-24 13:39:32 -07003429 def app( self, appName, option ):
3430 """
3431 Interacts with the app command for ONOS. This command manages
3432 application inventory.
3433 """
Jon Hallbe379602015-03-24 13:39:32 -07003434 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003435 # Validate argument types
3436 valid = True
3437 if not isinstance( appName, types.StringType ):
3438 main.log.error( self.name + ".app(): appName must be a " +
3439 "string" )
3440 valid = False
3441 if not isinstance( option, types.StringType ):
3442 main.log.error( self.name + ".app(): option must be a string" )
3443 valid = False
3444 if not valid:
3445 return main.FALSE
3446 # Validate Option
3447 option = option.lower()
3448 # NOTE: Install may become a valid option
3449 if option == "activate":
3450 pass
3451 elif option == "deactivate":
3452 pass
3453 elif option == "uninstall":
3454 pass
3455 else:
3456 # Invalid option
3457 main.log.error( "The ONOS app command argument only takes " +
3458 "the values: (activate|deactivate|uninstall)" +
3459 "; was given '" + option + "'")
3460 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003461 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003462 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003463 if "Error executing command" in output:
3464 main.log.error( "Error in processing onos:app command: " +
3465 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003466 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003467 elif "No such application" in output:
3468 main.log.error( "The application '" + appName +
3469 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003470 return main.FALSE
3471 elif "Command not found:" in output:
3472 main.log.error( "Error in processing onos:app command: " +
3473 str( output ) )
3474 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003475 elif "Unsupported command:" in output:
3476 main.log.error( "Incorrect command given to 'app': " +
3477 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003478 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003479 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003480 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003481 return main.TRUE
3482 except TypeError:
3483 main.log.exception( self.name + ": Object not as expected" )
3484 return main.ERROR
3485 except pexpect.EOF:
3486 main.log.error( self.name + ": EOF exception found" )
3487 main.log.error( self.name + ": " + self.handle.before )
3488 main.cleanup()
3489 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003490 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003491 main.log.exception( self.name + ": Uncaught exception!" )
3492 main.cleanup()
3493 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003494
Jon Hallbd16b922015-03-26 17:53:15 -07003495 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003496 """
3497 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003498 appName is the hierarchical app name, not the feature name
3499 If check is True, method will check the status of the app after the
3500 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003501 Returns main.TRUE if the command was successfully sent
3502 main.FALSE if the cli responded with an error or given
3503 incorrect input
3504 """
3505 try:
3506 if not isinstance( appName, types.StringType ):
3507 main.log.error( self.name + ".activateApp(): appName must be" +
3508 " a string" )
3509 return main.FALSE
3510 status = self.appStatus( appName )
3511 if status == "INSTALLED":
3512 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003513 if check and response == main.TRUE:
3514 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003515 status = self.appStatus( appName )
3516 if status == "ACTIVE":
3517 return main.TRUE
3518 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003519 main.log.debug( "The state of application " +
3520 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003521 time.sleep( 1 )
3522 return main.FALSE
3523 else: # not 'check' or command didn't succeed
3524 return response
Jon Hall146f1522015-03-24 15:33:24 -07003525 elif status == "ACTIVE":
3526 return main.TRUE
3527 elif status == "UNINSTALLED":
3528 main.log.error( self.name + ": Tried to activate the " +
3529 "application '" + appName + "' which is not " +
3530 "installed." )
3531 else:
3532 main.log.error( "Unexpected return value from appStatus: " +
3533 str( status ) )
3534 return main.ERROR
3535 except TypeError:
3536 main.log.exception( self.name + ": Object not as expected" )
3537 return main.ERROR
3538 except pexpect.EOF:
3539 main.log.error( self.name + ": EOF exception found" )
3540 main.log.error( self.name + ": " + self.handle.before )
3541 main.cleanup()
3542 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003543 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003544 main.log.exception( self.name + ": Uncaught exception!" )
3545 main.cleanup()
3546 main.exit()
3547
Jon Hallbd16b922015-03-26 17:53:15 -07003548 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003549 """
3550 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003551 appName is the hierarchical app name, not the feature name
3552 If check is True, method will check the status of the app after the
3553 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003554 Returns main.TRUE if the command was successfully sent
3555 main.FALSE if the cli responded with an error or given
3556 incorrect input
3557 """
3558 try:
3559 if not isinstance( appName, types.StringType ):
3560 main.log.error( self.name + ".deactivateApp(): appName must " +
3561 "be a string" )
3562 return main.FALSE
3563 status = self.appStatus( appName )
3564 if status == "INSTALLED":
3565 return main.TRUE
3566 elif status == "ACTIVE":
3567 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003568 if check and response == main.TRUE:
3569 for i in range(10): # try 10 times then give up
3570 status = self.appStatus( appName )
3571 if status == "INSTALLED":
3572 return main.TRUE
3573 else:
3574 time.sleep( 1 )
3575 return main.FALSE
3576 else: # not check or command didn't succeed
3577 return response
Jon Hall146f1522015-03-24 15:33:24 -07003578 elif status == "UNINSTALLED":
3579 main.log.warn( self.name + ": Tried to deactivate the " +
3580 "application '" + appName + "' which is not " +
3581 "installed." )
3582 return main.TRUE
3583 else:
3584 main.log.error( "Unexpected return value from appStatus: " +
3585 str( status ) )
3586 return main.ERROR
3587 except TypeError:
3588 main.log.exception( self.name + ": Object not as expected" )
3589 return main.ERROR
3590 except pexpect.EOF:
3591 main.log.error( self.name + ": EOF exception found" )
3592 main.log.error( self.name + ": " + self.handle.before )
3593 main.cleanup()
3594 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003595 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003596 main.log.exception( self.name + ": Uncaught exception!" )
3597 main.cleanup()
3598 main.exit()
3599
Jon Hallbd16b922015-03-26 17:53:15 -07003600 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003601 """
3602 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003603 appName is the hierarchical app name, not the feature name
3604 If check is True, method will check the status of the app after the
3605 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003606 Returns main.TRUE if the command was successfully sent
3607 main.FALSE if the cli responded with an error or given
3608 incorrect input
3609 """
3610 # TODO: check with Thomas about the state machine for apps
3611 try:
3612 if not isinstance( appName, types.StringType ):
3613 main.log.error( self.name + ".uninstallApp(): appName must " +
3614 "be a string" )
3615 return main.FALSE
3616 status = self.appStatus( appName )
3617 if status == "INSTALLED":
3618 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003619 if check and response == main.TRUE:
3620 for i in range(10): # try 10 times then give up
3621 status = self.appStatus( appName )
3622 if status == "UNINSTALLED":
3623 return main.TRUE
3624 else:
3625 time.sleep( 1 )
3626 return main.FALSE
3627 else: # not check or command didn't succeed
3628 return response
Jon Hall146f1522015-03-24 15:33:24 -07003629 elif status == "ACTIVE":
3630 main.log.warn( self.name + ": Tried to uninstall the " +
3631 "application '" + appName + "' which is " +
3632 "currently active." )
3633 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003634 if check and response == main.TRUE:
3635 for i in range(10): # try 10 times then give up
3636 status = self.appStatus( appName )
3637 if status == "UNINSTALLED":
3638 return main.TRUE
3639 else:
3640 time.sleep( 1 )
3641 return main.FALSE
3642 else: # not check or command didn't succeed
3643 return response
Jon Hall146f1522015-03-24 15:33:24 -07003644 elif status == "UNINSTALLED":
3645 return main.TRUE
3646 else:
3647 main.log.error( "Unexpected return value from appStatus: " +
3648 str( status ) )
3649 return main.ERROR
3650 except TypeError:
3651 main.log.exception( self.name + ": Object not as expected" )
3652 return main.ERROR
3653 except pexpect.EOF:
3654 main.log.error( self.name + ": EOF exception found" )
3655 main.log.error( self.name + ": " + self.handle.before )
3656 main.cleanup()
3657 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003658 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003659 main.log.exception( self.name + ": Uncaught exception!" )
3660 main.cleanup()
3661 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003662
3663 def appIDs( self, jsonFormat=True ):
3664 """
3665 Show the mappings between app id and app names given by the 'app-ids'
3666 cli command
3667 """
3668 try:
3669 cmdStr = "app-ids"
3670 if jsonFormat:
3671 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003672 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003673 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003674 assert "Command not found:" not in output, output
3675 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003677 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003678 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003679 return None
3680 except TypeError:
3681 main.log.exception( self.name + ": Object not as expected" )
3682 return None
3683 except pexpect.EOF:
3684 main.log.error( self.name + ": EOF exception found" )
3685 main.log.error( self.name + ": " + self.handle.before )
3686 main.cleanup()
3687 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003688 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003689 main.log.exception( self.name + ": Uncaught exception!" )
3690 main.cleanup()
3691 main.exit()
3692
3693 def appToIDCheck( self ):
3694 """
3695 This method will check that each application's ID listed in 'apps' is
3696 the same as the ID listed in 'app-ids'. The check will also check that
3697 there are no duplicate IDs issued. Note that an app ID should be
3698 a globaly unique numerical identifier for app/app-like features. Once
3699 an ID is registered, the ID is never freed up so that if an app is
3700 reinstalled it will have the same ID.
3701
3702 Returns: main.TRUE if the check passes and
3703 main.FALSE if the check fails or
3704 main.ERROR if there is some error in processing the test
3705 """
3706 try:
Jon Hall390696c2015-05-05 17:13:41 -07003707 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003708 rawJson = self.appIDs( jsonFormat=True )
3709 if rawJson:
3710 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003711 else:
Jon Hallc6793552016-01-19 14:18:37 -08003712 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003713 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003714 rawJson = self.apps( jsonFormat=True )
3715 if rawJson:
3716 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003717 else:
Jon Hallc6793552016-01-19 14:18:37 -08003718 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003719 bail = True
3720 if bail:
3721 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003722 result = main.TRUE
3723 for app in apps:
3724 appID = app.get( 'id' )
3725 if appID is None:
3726 main.log.error( "Error parsing app: " + str( app ) )
3727 result = main.FALSE
3728 appName = app.get( 'name' )
3729 if appName is None:
3730 main.log.error( "Error parsing app: " + str( app ) )
3731 result = main.FALSE
3732 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003733 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003734 # main.log.debug( "Comparing " + str( app ) + " to " +
3735 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003736 if not current: # if ids doesn't have this id
3737 result = main.FALSE
3738 main.log.error( "'app-ids' does not have the ID for " +
3739 str( appName ) + " that apps does." )
3740 elif len( current ) > 1:
3741 # there is more than one app with this ID
3742 result = main.FALSE
3743 # We will log this later in the method
3744 elif not current[0][ 'name' ] == appName:
3745 currentName = current[0][ 'name' ]
3746 result = main.FALSE
3747 main.log.error( "'app-ids' has " + str( currentName ) +
3748 " registered under id:" + str( appID ) +
3749 " but 'apps' has " + str( appName ) )
3750 else:
3751 pass # id and name match!
3752 # now make sure that app-ids has no duplicates
3753 idsList = []
3754 namesList = []
3755 for item in ids:
3756 idsList.append( item[ 'id' ] )
3757 namesList.append( item[ 'name' ] )
3758 if len( idsList ) != len( set( idsList ) ) or\
3759 len( namesList ) != len( set( namesList ) ):
3760 main.log.error( "'app-ids' has some duplicate entries: \n"
3761 + json.dumps( ids,
3762 sort_keys=True,
3763 indent=4,
3764 separators=( ',', ': ' ) ) )
3765 result = main.FALSE
3766 return result
Jon Hallc6793552016-01-19 14:18:37 -08003767 except ( TypeError, ValueError ):
3768 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003769 return main.ERROR
3770 except pexpect.EOF:
3771 main.log.error( self.name + ": EOF exception found" )
3772 main.log.error( self.name + ": " + self.handle.before )
3773 main.cleanup()
3774 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003775 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003776 main.log.exception( self.name + ": Uncaught exception!" )
3777 main.cleanup()
3778 main.exit()
3779
Jon Hallfb760a02015-04-13 15:35:03 -07003780 def getCfg( self, component=None, propName=None, short=False,
3781 jsonFormat=True ):
3782 """
3783 Get configuration settings from onos cli
3784 Optional arguments:
3785 component - Optionally only list configurations for a specific
3786 component. If None, all components with configurations
3787 are displayed. Case Sensitive string.
3788 propName - If component is specified, propName option will show
3789 only this specific configuration from that component.
3790 Case Sensitive string.
3791 jsonFormat - Returns output as json. Note that this will override
3792 the short option
3793 short - Short, less verbose, version of configurations.
3794 This is overridden by the json option
3795 returns:
3796 Output from cli as a string or None on error
3797 """
3798 try:
3799 baseStr = "cfg"
3800 cmdStr = " get"
3801 componentStr = ""
3802 if component:
3803 componentStr += " " + component
3804 if propName:
3805 componentStr += " " + propName
3806 if jsonFormat:
3807 baseStr += " -j"
3808 elif short:
3809 baseStr += " -s"
3810 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003811 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003812 assert "Command not found:" not in output, output
3813 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003814 return output
3815 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003816 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003817 return None
3818 except TypeError:
3819 main.log.exception( self.name + ": Object not as expected" )
3820 return None
3821 except pexpect.EOF:
3822 main.log.error( self.name + ": EOF exception found" )
3823 main.log.error( self.name + ": " + self.handle.before )
3824 main.cleanup()
3825 main.exit()
3826 except Exception:
3827 main.log.exception( self.name + ": Uncaught exception!" )
3828 main.cleanup()
3829 main.exit()
3830
3831 def setCfg( self, component, propName, value=None, check=True ):
3832 """
3833 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003834 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003835 component - The case sensitive name of the component whose
3836 property is to be set
3837 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003838 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003839 value - The value to set the property to. If None, will unset the
3840 property and revert it to it's default value(if applicable)
3841 check - Boolean, Check whether the option was successfully set this
3842 only applies when a value is given.
3843 returns:
3844 main.TRUE on success or main.FALSE on failure. If check is False,
3845 will return main.TRUE unless there is an error
3846 """
3847 try:
3848 baseStr = "cfg"
3849 cmdStr = " set " + str( component ) + " " + str( propName )
3850 if value is not None:
3851 cmdStr += " " + str( value )
3852 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003853 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003854 assert "Command not found:" not in output, output
3855 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003856 if value and check:
3857 results = self.getCfg( component=str( component ),
3858 propName=str( propName ),
3859 jsonFormat=True )
3860 # Check if current value is what we just set
3861 try:
3862 jsonOutput = json.loads( results )
3863 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003864 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003865 main.log.exception( "Error parsing cfg output" )
3866 main.log.error( "output:" + repr( results ) )
3867 return main.FALSE
3868 if current == str( value ):
3869 return main.TRUE
3870 return main.FALSE
3871 return main.TRUE
3872 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003873 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003874 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003875 except ( TypeError, ValueError ):
3876 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003877 return main.FALSE
3878 except pexpect.EOF:
3879 main.log.error( self.name + ": EOF exception found" )
3880 main.log.error( self.name + ": " + self.handle.before )
3881 main.cleanup()
3882 main.exit()
3883 except Exception:
3884 main.log.exception( self.name + ": Uncaught exception!" )
3885 main.cleanup()
3886 main.exit()
3887
Jon Hall390696c2015-05-05 17:13:41 -07003888 def setTestAdd( self, setName, values ):
3889 """
3890 CLI command to add elements to a distributed set.
3891 Arguments:
3892 setName - The name of the set to add to.
3893 values - The value(s) to add to the set, space seperated.
3894 Example usages:
3895 setTestAdd( "set1", "a b c" )
3896 setTestAdd( "set2", "1" )
3897 returns:
3898 main.TRUE on success OR
3899 main.FALSE if elements were already in the set OR
3900 main.ERROR on error
3901 """
3902 try:
3903 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3904 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003905 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003906 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003907 try:
3908 # TODO: Maybe make this less hardcoded
3909 # ConsistentMap Exceptions
3910 assert "org.onosproject.store.service" not in output
3911 # Node not leader
3912 assert "java.lang.IllegalStateException" not in output
3913 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003914 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003915 "command: " + str( output ) )
3916 retryTime = 30 # Conservative time, given by Madan
3917 main.log.info( "Waiting " + str( retryTime ) +
3918 "seconds before retrying." )
3919 time.sleep( retryTime ) # Due to change in mastership
3920 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003921 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003922 assert "Error executing command" not in output
3923 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3924 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3925 main.log.info( self.name + ": " + output )
3926 if re.search( positiveMatch, output):
3927 return main.TRUE
3928 elif re.search( negativeMatch, output):
3929 return main.FALSE
3930 else:
3931 main.log.error( self.name + ": setTestAdd did not" +
3932 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003933 main.log.debug( self.name + " actual: " + repr( output ) )
3934 return main.ERROR
3935 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003936 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003937 return main.ERROR
3938 except TypeError:
3939 main.log.exception( self.name + ": Object not as expected" )
3940 return main.ERROR
3941 except pexpect.EOF:
3942 main.log.error( self.name + ": EOF exception found" )
3943 main.log.error( self.name + ": " + self.handle.before )
3944 main.cleanup()
3945 main.exit()
3946 except Exception:
3947 main.log.exception( self.name + ": Uncaught exception!" )
3948 main.cleanup()
3949 main.exit()
3950
3951 def setTestRemove( self, setName, values, clear=False, retain=False ):
3952 """
3953 CLI command to remove elements from a distributed set.
3954 Required arguments:
3955 setName - The name of the set to remove from.
3956 values - The value(s) to remove from the set, space seperated.
3957 Optional arguments:
3958 clear - Clear all elements from the set
3959 retain - Retain only the given values. (intersection of the
3960 original set and the given set)
3961 returns:
3962 main.TRUE on success OR
3963 main.FALSE if the set was not changed OR
3964 main.ERROR on error
3965 """
3966 try:
3967 cmdStr = "set-test-remove "
3968 if clear:
3969 cmdStr += "-c " + str( setName )
3970 elif retain:
3971 cmdStr += "-r " + str( setName ) + " " + str( values )
3972 else:
3973 cmdStr += str( setName ) + " " + str( values )
3974 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003975 try:
Jon Halla495f562016-05-16 18:03:26 -07003976 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003977 # TODO: Maybe make this less hardcoded
3978 # ConsistentMap Exceptions
3979 assert "org.onosproject.store.service" not in output
3980 # Node not leader
3981 assert "java.lang.IllegalStateException" not in output
3982 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003983 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003984 "command: " + str( output ) )
3985 retryTime = 30 # Conservative time, given by Madan
3986 main.log.info( "Waiting " + str( retryTime ) +
3987 "seconds before retrying." )
3988 time.sleep( retryTime ) # Due to change in mastership
3989 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003990 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003991 assert "Command not found:" not in output, output
3992 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003993 main.log.info( self.name + ": " + output )
3994 if clear:
3995 pattern = "Set " + str( setName ) + " cleared"
3996 if re.search( pattern, output ):
3997 return main.TRUE
3998 elif retain:
3999 positivePattern = str( setName ) + " was pruned to contain " +\
4000 "only elements of set \[(.*)\]"
4001 negativePattern = str( setName ) + " was not changed by " +\
4002 "retaining only elements of the set " +\
4003 "\[(.*)\]"
4004 if re.search( positivePattern, output ):
4005 return main.TRUE
4006 elif re.search( negativePattern, output ):
4007 return main.FALSE
4008 else:
4009 positivePattern = "\[(.*)\] was removed from the set " +\
4010 str( setName )
4011 if ( len( values.split() ) == 1 ):
4012 negativePattern = "\[(.*)\] was not in set " +\
4013 str( setName )
4014 else:
4015 negativePattern = "No element of \[(.*)\] was in set " +\
4016 str( setName )
4017 if re.search( positivePattern, output ):
4018 return main.TRUE
4019 elif re.search( negativePattern, output ):
4020 return main.FALSE
4021 main.log.error( self.name + ": setTestRemove did not" +
4022 " match expected output" )
4023 main.log.debug( self.name + " expected: " + pattern )
4024 main.log.debug( self.name + " actual: " + repr( output ) )
4025 return main.ERROR
4026 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004027 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004028 return main.ERROR
4029 except TypeError:
4030 main.log.exception( self.name + ": Object not as expected" )
4031 return main.ERROR
4032 except pexpect.EOF:
4033 main.log.error( self.name + ": EOF exception found" )
4034 main.log.error( self.name + ": " + self.handle.before )
4035 main.cleanup()
4036 main.exit()
4037 except Exception:
4038 main.log.exception( self.name + ": Uncaught exception!" )
4039 main.cleanup()
4040 main.exit()
4041
4042 def setTestGet( self, setName, values="" ):
4043 """
4044 CLI command to get the elements in a distributed set.
4045 Required arguments:
4046 setName - The name of the set to remove from.
4047 Optional arguments:
4048 values - The value(s) to check if in the set, space seperated.
4049 returns:
4050 main.ERROR on error OR
4051 A list of elements in the set if no optional arguments are
4052 supplied OR
4053 A tuple containing the list then:
4054 main.FALSE if the given values are not in the set OR
4055 main.TRUE if the given values are in the set OR
4056 """
4057 try:
4058 values = str( values ).strip()
4059 setName = str( setName ).strip()
4060 length = len( values.split() )
4061 containsCheck = None
4062 # Patterns to match
4063 setPattern = "\[(.*)\]"
4064 pattern = "Items in set " + setName + ":\n" + setPattern
4065 containsTrue = "Set " + setName + " contains the value " + values
4066 containsFalse = "Set " + setName + " did not contain the value " +\
4067 values
4068 containsAllTrue = "Set " + setName + " contains the the subset " +\
4069 setPattern
4070 containsAllFalse = "Set " + setName + " did not contain the the" +\
4071 " subset " + setPattern
4072
4073 cmdStr = "set-test-get "
4074 cmdStr += setName + " " + values
4075 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004076 try:
Jon Halla495f562016-05-16 18:03:26 -07004077 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004078 # TODO: Maybe make this less hardcoded
4079 # ConsistentMap Exceptions
4080 assert "org.onosproject.store.service" not in output
4081 # Node not leader
4082 assert "java.lang.IllegalStateException" not in output
4083 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004084 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004085 "command: " + str( output ) )
4086 retryTime = 30 # Conservative time, given by Madan
4087 main.log.info( "Waiting " + str( retryTime ) +
4088 "seconds before retrying." )
4089 time.sleep( retryTime ) # Due to change in mastership
4090 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004091 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004092 assert "Command not found:" not in output, output
4093 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004094 main.log.info( self.name + ": " + output )
4095
4096 if length == 0:
4097 match = re.search( pattern, output )
4098 else: # if given values
4099 if length == 1: # Contains output
4100 patternTrue = pattern + "\n" + containsTrue
4101 patternFalse = pattern + "\n" + containsFalse
4102 else: # ContainsAll output
4103 patternTrue = pattern + "\n" + containsAllTrue
4104 patternFalse = pattern + "\n" + containsAllFalse
4105 matchTrue = re.search( patternTrue, output )
4106 matchFalse = re.search( patternFalse, output )
4107 if matchTrue:
4108 containsCheck = main.TRUE
4109 match = matchTrue
4110 elif matchFalse:
4111 containsCheck = main.FALSE
4112 match = matchFalse
4113 else:
4114 main.log.error( self.name + " setTestGet did not match " +\
4115 "expected output" )
4116 main.log.debug( self.name + " expected: " + pattern )
4117 main.log.debug( self.name + " actual: " + repr( output ) )
4118 match = None
4119 if match:
4120 setMatch = match.group( 1 )
4121 if setMatch == '':
4122 setList = []
4123 else:
4124 setList = setMatch.split( ", " )
4125 if length > 0:
4126 return ( setList, containsCheck )
4127 else:
4128 return setList
4129 else: # no match
4130 main.log.error( self.name + ": setTestGet did not" +
4131 " match expected output" )
4132 main.log.debug( self.name + " expected: " + pattern )
4133 main.log.debug( self.name + " actual: " + repr( output ) )
4134 return main.ERROR
4135 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004136 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004137 return main.ERROR
4138 except TypeError:
4139 main.log.exception( self.name + ": Object not as expected" )
4140 return main.ERROR
4141 except pexpect.EOF:
4142 main.log.error( self.name + ": EOF exception found" )
4143 main.log.error( self.name + ": " + self.handle.before )
4144 main.cleanup()
4145 main.exit()
4146 except Exception:
4147 main.log.exception( self.name + ": Uncaught exception!" )
4148 main.cleanup()
4149 main.exit()
4150
4151 def setTestSize( self, setName ):
4152 """
4153 CLI command to get the elements in a distributed set.
4154 Required arguments:
4155 setName - The name of the set to remove from.
4156 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004157 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004158 None on error
4159 """
4160 try:
4161 # TODO: Should this check against the number of elements returned
4162 # and then return true/false based on that?
4163 setName = str( setName ).strip()
4164 # Patterns to match
4165 setPattern = "\[(.*)\]"
4166 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4167 setPattern
4168 cmdStr = "set-test-get -s "
4169 cmdStr += setName
4170 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004171 try:
Jon Halla495f562016-05-16 18:03:26 -07004172 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004173 # TODO: Maybe make this less hardcoded
4174 # ConsistentMap Exceptions
4175 assert "org.onosproject.store.service" not in output
4176 # Node not leader
4177 assert "java.lang.IllegalStateException" not in output
4178 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004179 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004180 "command: " + str( output ) )
4181 retryTime = 30 # Conservative time, given by Madan
4182 main.log.info( "Waiting " + str( retryTime ) +
4183 "seconds before retrying." )
4184 time.sleep( retryTime ) # Due to change in mastership
4185 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004186 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004187 assert "Command not found:" not in output, output
4188 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004189 main.log.info( self.name + ": " + output )
4190 match = re.search( pattern, output )
4191 if match:
4192 setSize = int( match.group( 1 ) )
4193 setMatch = match.group( 2 )
4194 if len( setMatch.split() ) == setSize:
4195 main.log.info( "The size returned by " + self.name +
4196 " matches the number of elements in " +
4197 "the returned set" )
4198 else:
4199 main.log.error( "The size returned by " + self.name +
4200 " does not match the number of " +
4201 "elements in the returned set." )
4202 return setSize
4203 else: # no match
4204 main.log.error( self.name + ": setTestGet did not" +
4205 " match expected output" )
4206 main.log.debug( self.name + " expected: " + pattern )
4207 main.log.debug( self.name + " actual: " + repr( output ) )
4208 return None
4209 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004210 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004211 return None
Jon Hall390696c2015-05-05 17:13:41 -07004212 except TypeError:
4213 main.log.exception( self.name + ": Object not as expected" )
4214 return None
4215 except pexpect.EOF:
4216 main.log.error( self.name + ": EOF exception found" )
4217 main.log.error( self.name + ": " + self.handle.before )
4218 main.cleanup()
4219 main.exit()
4220 except Exception:
4221 main.log.exception( self.name + ": Uncaught exception!" )
4222 main.cleanup()
4223 main.exit()
4224
Jon Hall80daded2015-05-27 16:07:00 -07004225 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004226 """
4227 Command to list the various counters in the system.
4228 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004229 if jsonFormat, a string of the json object returned by the cli
4230 command
4231 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004232 None on error
4233 """
Jon Hall390696c2015-05-05 17:13:41 -07004234 try:
4235 counters = {}
4236 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004237 if jsonFormat:
4238 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004239 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004240 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004241 assert "Command not found:" not in output, output
4242 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004243 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004244 return output
Jon Hall390696c2015-05-05 17:13:41 -07004245 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004246 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004247 return None
Jon Hall390696c2015-05-05 17:13:41 -07004248 except TypeError:
4249 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004250 return None
Jon Hall390696c2015-05-05 17:13:41 -07004251 except pexpect.EOF:
4252 main.log.error( self.name + ": EOF exception found" )
4253 main.log.error( self.name + ": " + self.handle.before )
4254 main.cleanup()
4255 main.exit()
4256 except Exception:
4257 main.log.exception( self.name + ": Uncaught exception!" )
4258 main.cleanup()
4259 main.exit()
4260
Jon Hall935db192016-04-19 00:22:04 -07004261 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004262 """
Jon Halle1a3b752015-07-22 13:02:46 -07004263 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004264 Required arguments:
4265 counter - The name of the counter to increment.
4266 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004267 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004268 returns:
4269 integer value of the counter or
4270 None on Error
4271 """
4272 try:
4273 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004274 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004275 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004276 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004277 if delta != 1:
4278 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004279 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004280 try:
Jon Halla495f562016-05-16 18:03:26 -07004281 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004282 # TODO: Maybe make this less hardcoded
4283 # ConsistentMap Exceptions
4284 assert "org.onosproject.store.service" not in output
4285 # Node not leader
4286 assert "java.lang.IllegalStateException" not in output
4287 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004288 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004289 "command: " + str( output ) )
4290 retryTime = 30 # Conservative time, given by Madan
4291 main.log.info( "Waiting " + str( retryTime ) +
4292 "seconds before retrying." )
4293 time.sleep( retryTime ) # Due to change in mastership
4294 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004295 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004296 assert "Command not found:" not in output, output
4297 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004298 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004299 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004300 match = re.search( pattern, output )
4301 if match:
4302 return int( match.group( 1 ) )
4303 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004304 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004305 " match expected output." )
4306 main.log.debug( self.name + " expected: " + pattern )
4307 main.log.debug( self.name + " actual: " + repr( output ) )
4308 return None
4309 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004310 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004311 return None
4312 except TypeError:
4313 main.log.exception( self.name + ": Object not as expected" )
4314 return None
4315 except pexpect.EOF:
4316 main.log.error( self.name + ": EOF exception found" )
4317 main.log.error( self.name + ": " + self.handle.before )
4318 main.cleanup()
4319 main.exit()
4320 except Exception:
4321 main.log.exception( self.name + ": Uncaught exception!" )
4322 main.cleanup()
4323 main.exit()
4324
Jon Hall935db192016-04-19 00:22:04 -07004325 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004326 """
4327 CLI command to get a distributed counter then add a delta to it.
4328 Required arguments:
4329 counter - The name of the counter to increment.
4330 Optional arguments:
4331 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004332 returns:
4333 integer value of the counter or
4334 None on Error
4335 """
4336 try:
4337 counter = str( counter )
4338 delta = int( delta )
4339 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004340 cmdStr += counter
4341 if delta != 1:
4342 cmdStr += " " + str( delta )
4343 output = self.sendline( cmdStr )
4344 try:
Jon Halla495f562016-05-16 18:03:26 -07004345 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004346 # TODO: Maybe make this less hardcoded
4347 # ConsistentMap Exceptions
4348 assert "org.onosproject.store.service" not in output
4349 # Node not leader
4350 assert "java.lang.IllegalStateException" not in output
4351 except AssertionError:
4352 main.log.error( "Error in processing '" + cmdStr + "' " +
4353 "command: " + str( output ) )
4354 retryTime = 30 # Conservative time, given by Madan
4355 main.log.info( "Waiting " + str( retryTime ) +
4356 "seconds before retrying." )
4357 time.sleep( retryTime ) # Due to change in mastership
4358 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004359 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004360 assert "Command not found:" not in output, output
4361 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004362 main.log.info( self.name + ": " + output )
4363 pattern = counter + " was updated to (-?\d+)"
4364 match = re.search( pattern, output )
4365 if match:
4366 return int( match.group( 1 ) )
4367 else:
4368 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4369 " match expected output." )
4370 main.log.debug( self.name + " expected: " + pattern )
4371 main.log.debug( self.name + " actual: " + repr( output ) )
4372 return None
4373 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004374 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004375 return None
4376 except TypeError:
4377 main.log.exception( self.name + ": Object not as expected" )
4378 return None
4379 except pexpect.EOF:
4380 main.log.error( self.name + ": EOF exception found" )
4381 main.log.error( self.name + ": " + self.handle.before )
4382 main.cleanup()
4383 main.exit()
4384 except Exception:
4385 main.log.exception( self.name + ": Uncaught exception!" )
4386 main.cleanup()
4387 main.exit()
4388
YPZhangfebf7302016-05-24 16:45:56 -07004389 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004390 """
4391 Description: Execute summary command in onos
4392 Returns: json object ( summary -j ), returns main.FALSE if there is
4393 no output
4394
4395 """
4396 try:
4397 cmdStr = "summary"
4398 if jsonFormat:
4399 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004400 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004401 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004402 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004403 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004404 if not handle:
4405 main.log.error( self.name + ": There is no output in " +
4406 "summary command" )
4407 return main.FALSE
4408 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004409 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004410 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004411 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004412 except TypeError:
4413 main.log.exception( self.name + ": Object not as expected" )
4414 return None
4415 except pexpect.EOF:
4416 main.log.error( self.name + ": EOF exception found" )
4417 main.log.error( self.name + ": " + self.handle.before )
4418 main.cleanup()
4419 main.exit()
4420 except Exception:
4421 main.log.exception( self.name + ": Uncaught exception!" )
4422 main.cleanup()
4423 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004424
Jon Hall935db192016-04-19 00:22:04 -07004425 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004426 """
4427 CLI command to get the value of a key in a consistent map using
4428 transactions. This a test function and can only get keys from the
4429 test map hard coded into the cli command
4430 Required arguments:
4431 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004432 returns:
4433 The string value of the key or
4434 None on Error
4435 """
4436 try:
4437 keyName = str( keyName )
4438 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004439 cmdStr += keyName
4440 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004441 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004442 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004443 try:
4444 # TODO: Maybe make this less hardcoded
4445 # ConsistentMap Exceptions
4446 assert "org.onosproject.store.service" not in output
4447 # Node not leader
4448 assert "java.lang.IllegalStateException" not in output
4449 except AssertionError:
4450 main.log.error( "Error in processing '" + cmdStr + "' " +
4451 "command: " + str( output ) )
4452 return None
4453 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4454 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004455 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004456 return None
4457 else:
4458 match = re.search( pattern, output )
4459 if match:
4460 return match.groupdict()[ 'value' ]
4461 else:
4462 main.log.error( self.name + ": transactionlMapGet did not" +
4463 " match expected output." )
4464 main.log.debug( self.name + " expected: " + pattern )
4465 main.log.debug( self.name + " actual: " + repr( output ) )
4466 return None
Jon Hallc6793552016-01-19 14:18:37 -08004467 except AssertionError:
4468 main.log.exception( "" )
4469 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return None
4473 except pexpect.EOF:
4474 main.log.error( self.name + ": EOF exception found" )
4475 main.log.error( self.name + ": " + self.handle.before )
4476 main.cleanup()
4477 main.exit()
4478 except Exception:
4479 main.log.exception( self.name + ": Uncaught exception!" )
4480 main.cleanup()
4481 main.exit()
4482
Jon Hall935db192016-04-19 00:22:04 -07004483 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004484 """
4485 CLI command to put a value into 'numKeys' number of keys in a
4486 consistent map using transactions. This a test function and can only
4487 put into keys named 'Key#' of the test map hard coded into the cli command
4488 Required arguments:
4489 numKeys - Number of keys to add the value to
4490 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004491 returns:
4492 A dictionary whose keys are the name of the keys put into the map
4493 and the values of the keys are dictionaries whose key-values are
4494 'value': value put into map and optionaly
4495 'oldValue': Previous value in the key or
4496 None on Error
4497
4498 Example output
4499 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4500 'Key2': {'value': 'Testing'} }
4501 """
4502 try:
4503 numKeys = str( numKeys )
4504 value = str( value )
4505 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004506 cmdStr += numKeys + " " + value
4507 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004508 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004509 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004510 try:
4511 # TODO: Maybe make this less hardcoded
4512 # ConsistentMap Exceptions
4513 assert "org.onosproject.store.service" not in output
4514 # Node not leader
4515 assert "java.lang.IllegalStateException" not in output
4516 except AssertionError:
4517 main.log.error( "Error in processing '" + cmdStr + "' " +
4518 "command: " + str( output ) )
4519 return None
4520 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4521 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4522 results = {}
4523 for line in output.splitlines():
4524 new = re.search( newPattern, line )
4525 updated = re.search( updatedPattern, line )
4526 if new:
4527 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4528 elif updated:
4529 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004530 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004531 else:
4532 main.log.error( self.name + ": transactionlMapGet did not" +
4533 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004534 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4535 newPattern,
4536 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004537 main.log.debug( self.name + " actual: " + repr( output ) )
4538 return results
Jon Hallc6793552016-01-19 14:18:37 -08004539 except AssertionError:
4540 main.log.exception( "" )
4541 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004542 except TypeError:
4543 main.log.exception( self.name + ": Object not as expected" )
4544 return None
4545 except pexpect.EOF:
4546 main.log.error( self.name + ": EOF exception found" )
4547 main.log.error( self.name + ": " + self.handle.before )
4548 main.cleanup()
4549 main.exit()
4550 except Exception:
4551 main.log.exception( self.name + ": Uncaught exception!" )
4552 main.cleanup()
4553 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004554
acsmarsdaea66c2015-09-03 11:44:06 -07004555 def maps( self, jsonFormat=True ):
4556 """
4557 Description: Returns result of onos:maps
4558 Optional:
4559 * jsonFormat: enable json formatting of output
4560 """
4561 try:
4562 cmdStr = "maps"
4563 if jsonFormat:
4564 cmdStr += " -j"
4565 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004566 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004567 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004568 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004569 except AssertionError:
4570 main.log.exception( "" )
4571 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004572 except TypeError:
4573 main.log.exception( self.name + ": Object not as expected" )
4574 return None
4575 except pexpect.EOF:
4576 main.log.error( self.name + ": EOF exception found" )
4577 main.log.error( self.name + ": " + self.handle.before )
4578 main.cleanup()
4579 main.exit()
4580 except Exception:
4581 main.log.exception( self.name + ": Uncaught exception!" )
4582 main.cleanup()
4583 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004584
4585 def getSwController( self, uri, jsonFormat=True ):
4586 """
4587 Descrition: Gets the controller information from the device
4588 """
4589 try:
4590 cmd = "device-controllers "
4591 if jsonFormat:
4592 cmd += "-j "
4593 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004594 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004595 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004596 return response
Jon Hallc6793552016-01-19 14:18:37 -08004597 except AssertionError:
4598 main.log.exception( "" )
4599 return None
GlennRC050596c2015-11-18 17:06:41 -08004600 except TypeError:
4601 main.log.exception( self.name + ": Object not as expected" )
4602 return None
4603 except pexpect.EOF:
4604 main.log.error( self.name + ": EOF exception found" )
4605 main.log.error( self.name + ": " + self.handle.before )
4606 main.cleanup()
4607 main.exit()
4608 except Exception:
4609 main.log.exception( self.name + ": Uncaught exception!" )
4610 main.cleanup()
4611 main.exit()
4612
4613 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4614 """
4615 Descrition: sets the controller(s) for the specified device
4616
4617 Parameters:
4618 Required: uri - String: The uri of the device(switch).
4619 ip - String or List: The ip address of the controller.
4620 This parameter can be formed in a couple of different ways.
4621 VALID:
4622 10.0.0.1 - just the ip address
4623 tcp:10.0.0.1 - the protocol and the ip address
4624 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4625 so that you can add controllers with different
4626 protocols and ports
4627 INVALID:
4628 10.0.0.1:6653 - this is not supported by ONOS
4629
4630 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4631 port - The port number.
4632 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4633
4634 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4635 """
4636 try:
4637 cmd = "device-setcontrollers"
4638
4639 if jsonFormat:
4640 cmd += " -j"
4641 cmd += " " + uri
4642 if isinstance( ip, str ):
4643 ip = [ip]
4644 for item in ip:
4645 if ":" in item:
4646 sitem = item.split( ":" )
4647 if len(sitem) == 3:
4648 cmd += " " + item
4649 elif "." in sitem[1]:
4650 cmd += " {}:{}".format(item, port)
4651 else:
4652 main.log.error( "Malformed entry: " + item )
4653 raise TypeError
4654 else:
4655 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004656 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004657 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004658 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004659 if "Error" in response:
4660 main.log.error( response )
4661 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004662 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004663 except AssertionError:
4664 main.log.exception( "" )
4665 return None
GlennRC050596c2015-11-18 17:06:41 -08004666 except TypeError:
4667 main.log.exception( self.name + ": Object not as expected" )
4668 return main.FALSE
4669 except pexpect.EOF:
4670 main.log.error( self.name + ": EOF exception found" )
4671 main.log.error( self.name + ": " + self.handle.before )
4672 main.cleanup()
4673 main.exit()
4674 except Exception:
4675 main.log.exception( self.name + ": Uncaught exception!" )
4676 main.cleanup()
4677 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004678
4679 def removeDevice( self, device ):
4680 '''
4681 Description:
4682 Remove a device from ONOS by passing the uri of the device(s).
4683 Parameters:
4684 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4685 Returns:
4686 Returns main.FALSE if an exception is thrown or an error is present
4687 in the response. Otherwise, returns main.TRUE.
4688 NOTE:
4689 If a host cannot be removed, then this function will return main.FALSE
4690 '''
4691 try:
4692 if type( device ) is str:
4693 device = list( device )
4694
4695 for d in device:
4696 time.sleep( 1 )
4697 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004698 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004699 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004700 if "Error" in response:
4701 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4702 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004703 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004704 except AssertionError:
4705 main.log.exception( "" )
4706 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004707 except TypeError:
4708 main.log.exception( self.name + ": Object not as expected" )
4709 return main.FALSE
4710 except pexpect.EOF:
4711 main.log.error( self.name + ": EOF exception found" )
4712 main.log.error( self.name + ": " + self.handle.before )
4713 main.cleanup()
4714 main.exit()
4715 except Exception:
4716 main.log.exception( self.name + ": Uncaught exception!" )
4717 main.cleanup()
4718 main.exit()
4719
4720 def removeHost( self, host ):
4721 '''
4722 Description:
4723 Remove a host from ONOS by passing the id of the host(s)
4724 Parameters:
4725 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4726 Returns:
4727 Returns main.FALSE if an exception is thrown or an error is present
4728 in the response. Otherwise, returns main.TRUE.
4729 NOTE:
4730 If a host cannot be removed, then this function will return main.FALSE
4731 '''
4732 try:
4733 if type( host ) is str:
4734 host = list( host )
4735
4736 for h in host:
4737 time.sleep( 1 )
4738 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004739 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004740 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004741 if "Error" in response:
4742 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4743 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004744 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004745 except AssertionError:
4746 main.log.exception( "" )
4747 return None
GlennRC20fc6522015-12-23 23:26:57 -08004748 except TypeError:
4749 main.log.exception( self.name + ": Object not as expected" )
4750 return main.FALSE
4751 except pexpect.EOF:
4752 main.log.error( self.name + ": EOF exception found" )
4753 main.log.error( self.name + ": " + self.handle.before )
4754 main.cleanup()
4755 main.exit()
4756 except Exception:
4757 main.log.exception( self.name + ": Uncaught exception!" )
4758 main.cleanup()
4759 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004760
YPZhangfebf7302016-05-24 16:45:56 -07004761 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004762 '''
4763 Description:
4764 Bring link down or up in the null-provider.
4765 params:
4766 begin - (string) One end of a device or switch.
4767 end - (string) the other end of the device or switch
4768 returns:
4769 main.TRUE if no exceptions were thrown and no Errors are
4770 present in the resoponse. Otherwise, returns main.FALSE
4771 '''
4772 try:
Jon Hallc6793552016-01-19 14:18:37 -08004773 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004774 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004775 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004776 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004777 if "Error" in response or "Failure" in response:
4778 main.log.error( response )
4779 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004780 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004781 except AssertionError:
4782 main.log.exception( "" )
4783 return None
GlennRCed771242016-01-13 17:02:47 -08004784 except TypeError:
4785 main.log.exception( self.name + ": Object not as expected" )
4786 return main.FALSE
4787 except pexpect.EOF:
4788 main.log.error( self.name + ": EOF exception found" )
4789 main.log.error( self.name + ": " + self.handle.before )
4790 main.cleanup()
4791 main.exit()
4792 except Exception:
4793 main.log.exception( self.name + ": Uncaught exception!" )
4794 main.cleanup()
4795 main.exit()
4796
Flavio Castro82ee2f62016-06-07 15:04:12 -07004797 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4798 '''
4799 Description:
4800 Changes the state of port in an OF switch by means of the
4801 PORTSTATUS OF messages.
4802 params:
4803 dpid - (string) Datapath ID of the device
4804 port - (string) target port in the device
4805 state - (string) target state (enable or disabled)
4806 returns:
4807 main.TRUE if no exceptions were thrown and no Errors are
4808 present in the resoponse. Otherwise, returns main.FALSE
4809 '''
4810 try:
4811 cmd = "portstate {} {} {}".format( dpid, port, state )
4812 response = self.sendline( cmd, showResponse=True )
4813 assert response is not None, "Error in sendline"
4814 assert "Command not found:" not in response, response
4815 if "Error" in response or "Failure" in response:
4816 main.log.error( response )
4817 return main.FALSE
4818 return main.TRUE
4819 except AssertionError:
4820 main.log.exception( "" )
4821 return None
4822 except TypeError:
4823 main.log.exception( self.name + ": Object not as expected" )
4824 return main.FALSE
4825 except pexpect.EOF:
4826 main.log.error( self.name + ": EOF exception found" )
4827 main.log.error( self.name + ": " + self.handle.before )
4828 main.cleanup()
4829 main.exit()
4830 except Exception:
4831 main.log.exception( self.name + ": Uncaught exception!" )
4832 main.cleanup()
4833 main.exit()
4834
4835 def logSet( self, level="INFO", app="org.onosproject" ):
4836 """
4837 Set the logging level to lvl for a specific app
4838 returns main.TRUE on success
4839 returns main.FALSE if Error occurred
4840 if noExit is True, TestON will not exit, but clean up
4841 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4842 Level defaults to INFO
4843 """
4844 try:
4845 self.handle.sendline( "log:set %s %s" %( level, app ) )
4846 self.handle.expect( "onos>" )
4847
4848 response = self.handle.before
4849 if re.search( "Error", response ):
4850 return main.FALSE
4851 return main.TRUE
4852 except pexpect.TIMEOUT:
4853 main.log.exception( self.name + ": TIMEOUT exception found" )
4854 main.cleanup()
4855 main.exit()
4856 except pexpect.EOF:
4857 main.log.error( self.name + ": EOF exception found" )
4858 main.log.error( self.name + ": " + self.handle.before )
4859 main.cleanup()
4860 main.exit()
4861 except Exception:
4862 main.log.exception( self.name + ": Uncaught exception!" )
4863 main.cleanup()
4864 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004865
4866 def getGraphDict( self, timeout=60, includeHost=False ):
4867 """
4868 Return a dictionary which describes the latest network topology data as a
4869 graph.
4870 An example of the dictionary:
4871 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4872 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4873 Each vertex should at least have an 'edges' attribute which describes the
4874 adjacency information. The value of 'edges' attribute is also represented by
4875 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4876 list of attributes.
4877 An example of the edges dictionary:
4878 'edges': { vertex2: { 'port': ..., 'weight': ... },
4879 vertex3: { 'port': ..., 'weight': ... } }
4880 If includeHost == True, all hosts (and host-switch links) will be included
4881 in topology data.
4882 """
4883 graphDict = {}
4884 try:
4885 links = self.links()
4886 links = json.loads( links )
4887 devices = self.devices()
4888 devices = json.loads( devices )
4889 idToDevice = {}
4890 for device in devices:
4891 idToDevice[ device[ 'id' ] ] = device
4892 if includeHost:
4893 hosts = self.hosts()
4894 # FIXME: support 'includeHost' argument
4895 for link in links:
4896 nodeA = link[ 'src' ][ 'device' ]
4897 nodeB = link[ 'dst' ][ 'device' ]
4898 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4899 if not nodeA in graphDict.keys():
4900 graphDict[ nodeA ] = { 'edges':{},
4901 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4902 'type':idToDevice[ nodeA ][ 'type' ],
4903 'available':idToDevice[ nodeA ][ 'available' ],
4904 'role':idToDevice[ nodeA ][ 'role' ],
4905 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4906 'hw':idToDevice[ nodeA ][ 'hw' ],
4907 'sw':idToDevice[ nodeA ][ 'sw' ],
4908 'serial':idToDevice[ nodeA ][ 'serial' ],
4909 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4910 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4911 else:
4912 # Assert nodeB is not connected to any current links of nodeA
4913 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4914 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4915 'type':link[ 'type' ],
4916 'state':link[ 'state' ] }
4917 return graphDict
4918 except ( TypeError, ValueError ):
4919 main.log.exception( self.name + ": Object not as expected" )
4920 return None
4921 except KeyError:
4922 main.log.exception( self.name + ": KeyError exception found" )
4923 return None
4924 except AssertionError:
4925 main.log.exception( self.name + ": AssertionError exception found" )
4926 return None
4927 except pexpect.EOF:
4928 main.log.error( self.name + ": EOF exception found" )
4929 main.log.error( self.name + ": " + self.handle.before )
4930 return None
4931 except Exception:
4932 main.log.exception( self.name + ": Uncaught exception!" )
4933 return None