blob: 91a2509428b9c73c0729cfd6e3275ddfa55d1e58 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
Jeremy Songsterae01bba2016-07-11 15:39:17 -070017Modified 2016 by ON.Lab
18
19Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
20the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
21or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlab95ce8322014-10-13 14:12:04 -040022
kelvin8ec71442015-01-15 16:57:00 -080023"""
andrewonlab95ce8322014-10-13 14:12:04 -040024import pexpect
25import re
Jon Hall30b82fa2015-03-04 17:15:43 -080026import json
27import types
Jon Hallbd16b922015-03-26 17:53:15 -070028import time
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
andrewonlab95ce8322014-10-13 14:12:04 -040030from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070031from core.graph import Graph
andrewonlab95ce8322014-10-13 14:12:04 -040032
andrewonlab95ce8322014-10-13 14:12:04 -040033
kelvin8ec71442015-01-15 16:57:00 -080034class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070043 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080044 super( CLI, self ).__init__()
45
46 def connect( self, **connectargs ):
47 """
andrewonlab95ce8322014-10-13 14:12:04 -040048 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080049 """
andrewonlab95ce8322014-10-13 14:12:04 -040050 try:
51 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080052 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054 for key in self.options:
55 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080056 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040057 break
kelvin-onlabfb521662015-02-27 09:52:40 -080058 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070059 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040060
kelvin-onlaba4074292015-07-09 15:19:49 -070061 for key in self.options:
62 if key == 'onosIp':
63 self.onosIp = self.options[ 'onosIp' ]
64 break
65
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
68 try:
Jon Hallc6793552016-01-19 14:18:37 -080069 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070070 self.ip_address = os.getenv( str( self.ip_address ) )
71 else:
72 main.log.info( self.name +
73 ": Trying to connect to " +
74 self.ip_address )
75
76 except KeyError:
77 main.log.info( "Invalid host name," +
78 " connecting to local host instead" )
79 self.ip_address = 'localhost'
80 except Exception as inst:
81 main.log.error( "Uncaught exception: " + str( inst ) )
82
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080084 user_name=self.user_name,
85 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080086 port=self.port,
87 pwd=self.pwd,
88 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin8ec71442015-01-15 16:57:00 -080090 self.handle.sendline( "cd " + self.home )
91 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040092 if self.handle:
93 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080094 else:
95 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040096 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080097 except TypeError:
98 main.log.exception( self.name + ": Object not as expected" )
99 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800101 main.log.error( self.name + ": EOF exception found" )
102 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 main.cleanup()
104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 main.cleanup()
108 main.exit()
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def disconnect( self ):
111 """
andrewonlab95ce8322014-10-13 14:12:04 -0400112 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800113 """
Jon Halld61331b2015-02-17 16:35:47 -0800114 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400115 try:
Jon Hall61282e32015-03-19 11:34:11 -0700116 if self.handle:
117 i = self.logout()
118 if i == main.TRUE:
119 self.handle.sendline( "" )
120 self.handle.expect( "\$" )
121 self.handle.sendline( "exit" )
122 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800125 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700129 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700130 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700131 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400134 response = main.FALSE
135 return response
136
kelvin8ec71442015-01-15 16:57:00 -0800137 def logout( self ):
138 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700140 Returns main.TRUE if exited CLI and
141 main.FALSE on timeout (not guranteed you are disconnected)
142 None on TypeError
143 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800144 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500145 try:
Jon Hall61282e32015-03-19 11:34:11 -0700146 if self.handle:
147 self.handle.sendline( "" )
148 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
149 timeout=10 )
150 if i == 0: # In ONOS CLI
151 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700152 j = self.handle.expect( [ "\$",
153 "Command not found:",
154 pexpect.TIMEOUT ] )
155 if j == 0: # Successfully logged out
156 return main.TRUE
157 elif j == 1 or j == 2:
158 # ONOS didn't fully load, and logout command isn't working
159 # or the command timed out
160 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700161 try:
162 self.handle.expect( "\$" )
163 except pexpect.TIMEOUT:
164 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700165 return main.TRUE
166 else: # some other output
167 main.log.warn( "Unknown repsonse to logout command: '{}'",
168 repr( self.handle.before ) )
169 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700170 elif i == 1: # not in CLI
171 return main.TRUE
172 elif i == 3: # Timeout
173 return main.FALSE
174 else:
andrewonlab9627f432014-11-14 12:45:10 -0500175 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800176 except TypeError:
177 main.log.exception( self.name + ": Object not as expected" )
178 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800180 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700181 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700184 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700185 main.log.error( self.name +
186 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500189 main.cleanup()
190 main.exit()
191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
andrewonlab95ce8322014-10-13 14:12:04 -0400194 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800195
andrewonlab95ce8322014-10-13 14:12:04 -0400196 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800197 """
andrewonlab95ce8322014-10-13 14:12:04 -0400198 try:
199 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800200 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400201 main.cleanup()
202 main.exit()
203 else:
kelvin8ec71442015-01-15 16:57:00 -0800204 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800205 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800206 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400207 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800208 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800209 handleBefore = self.handle.before
210 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800211 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800212 self.handle.sendline("")
213 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800214 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 main.log.info( "Cell call returned: " + handleBefore +
217 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400218
219 return main.TRUE
220
Jon Halld4d4b372015-01-28 16:02:41 -0800221 except TypeError:
222 main.log.exception( self.name + ": Object not as expected" )
223 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( self.name + ": eof exception found" )
226 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400227 main.cleanup()
228 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800230 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400231 main.cleanup()
232 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800233
pingping-lin57a56ce2015-05-20 16:43:48 -0700234 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800235 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallefbd9792015-03-05 16:11:36 -0800237 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 by user would be used to set the current karaf shell idle timeout.
239 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800240 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 Below is an example to start a session with 60 seconds idle timeout
242 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800243
Hari Krishna25d42f72015-01-05 15:08:28 -0800244 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 Note: karafTimeout is left as str so that this could be read
248 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800249 """
You Wangf69ab392016-01-26 16:34:38 -0800250 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400251 try:
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
Chiyu Chengef109502016-11-21 15:51:38 -0800260 if waitForStart:
261 # Wait for onos start ( -w ) and enter onos cli
262 startCliCommand = "onos -w "
263 else:
264 startCliCommand = "onos "
265 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800266 i = self.handle.expect( [
267 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700268 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400269
270 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800272 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800273 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800274 "config:property-set -p org.apache.karaf.shell\
275 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800276 karafTimeout )
277 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800278 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800279 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400280 return main.TRUE
281 else:
kelvin8ec71442015-01-15 16:57:00 -0800282 # If failed, send ctrl+c to process and try again
283 main.log.info( "Starting CLI failed. Retrying..." )
284 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800285 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800286 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
287 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400288 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800290 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800291 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800292 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 "config:property-set -p org.apache.karaf.shell\
294 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800295 karafTimeout )
296 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800297 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800298 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400299 return main.TRUE
300 else:
kelvin8ec71442015-01-15 16:57:00 -0800301 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800302 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400303 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400304
Jon Halld4d4b372015-01-28 16:02:41 -0800305 except TypeError:
306 main.log.exception( self.name + ": Object not as expected" )
307 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800309 main.log.error( self.name + ": EOF exception found" )
310 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400311 main.cleanup()
312 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800313 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800314 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400315 main.cleanup()
316 main.exit()
317
suibin zhang116647a2016-05-06 16:30:09 -0700318 def startCellCli( self, karafTimeout="",
319 commandlineTimeout=10, onosStartTimeout=60 ):
320 """
321 Start CLI on onos ecll handle.
322
323 karafTimeout is an optional argument. karafTimeout value passed
324 by user would be used to set the current karaf shell idle timeout.
325 Note that when ever this property is modified the shell will exit and
326 the subsequent login would reflect new idle timeout.
327 Below is an example to start a session with 60 seconds idle timeout
328 ( input value is in milliseconds ):
329
330 tValue = "60000"
331
332 Note: karafTimeout is left as str so that this could be read
333 and passed to startOnosCli from PARAMS file as str.
334 """
335
336 try:
337 self.handle.sendline( "" )
338 x = self.handle.expect( [
339 "\$", "onos>" ], commandlineTimeout)
340
341 if x == 1:
342 main.log.info( "ONOS cli is already running" )
343 return main.TRUE
344
345 # Wait for onos start ( -w ) and enter onos cli
346 self.handle.sendline( "/opt/onos/bin/onos" )
347 i = self.handle.expect( [
348 "onos>",
349 pexpect.TIMEOUT ], onosStartTimeout )
350
351 if i == 0:
352 main.log.info( self.name + " CLI Started successfully" )
353 if karafTimeout:
354 self.handle.sendline(
355 "config:property-set -p org.apache.karaf.shell\
356 sshIdleTimeout " +
357 karafTimeout )
358 self.handle.expect( "\$" )
359 self.handle.sendline( "/opt/onos/bin/onos" )
360 self.handle.expect( "onos>" )
361 return main.TRUE
362 else:
363 # If failed, send ctrl+c to process and try again
364 main.log.info( "Starting CLI failed. Retrying..." )
365 self.handle.send( "\x03" )
366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
368 timeout=30 )
369 if i == 0:
370 main.log.info( self.name + " CLI Started " +
371 "successfully after retry attempt" )
372 if karafTimeout:
373 self.handle.sendline(
374 "config:property-set -p org.apache.karaf.shell\
375 sshIdleTimeout " +
376 karafTimeout )
377 self.handle.expect( "\$" )
378 self.handle.sendline( "/opt/onos/bin/onos" )
379 self.handle.expect( "onos>" )
380 return main.TRUE
381 else:
382 main.log.error( "Connection to CLI " +
383 self.name + " timeout" )
384 return main.FALSE
385
386 except TypeError:
387 main.log.exception( self.name + ": Object not as expected" )
388 return None
389 except pexpect.EOF:
390 main.log.error( self.name + ": EOF exception found" )
391 main.log.error( self.name + ": " + self.handle.before )
392 main.cleanup()
393 main.exit()
394 except Exception:
395 main.log.exception( self.name + ": Uncaught exception!" )
396 main.cleanup()
397 main.exit()
398
YPZhangebf9eb52016-05-12 15:20:24 -0700399 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800400 """
401 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800402 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800403 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700404 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800405 Available level: DEBUG, TRACE, INFO, WARN, ERROR
406 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800407 """
408 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800409 lvlStr = ""
410 if level:
411 lvlStr = "--level=" + level
412
kelvin-onlab338f5512015-02-06 10:53:16 -0800413 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700414 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800415 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800416
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 response = self.handle.before
418 if re.search( "Error", response ):
419 return main.FALSE
420 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700421 except pexpect.TIMEOUT:
422 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700423 if noExit:
424 main.cleanup()
425 return None
426 else:
427 main.cleanup()
428 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 except pexpect.EOF:
430 main.log.error( self.name + ": EOF exception found" )
431 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700432 if noExit:
433 main.cleanup()
434 return None
435 else:
436 main.cleanup()
437 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800438 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800439 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700440 if noExit:
441 main.cleanup()
442 return None
443 else:
444 main.cleanup()
445 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400446
YPZhangebf9eb52016-05-12 15:20:24 -0700447 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800448 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800449 Send a completely user specified string to
450 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400451 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800452
YPZhang14a4aa92016-07-15 13:37:15 -0700453 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700454
andrewonlaba18f6bf2014-10-13 19:31:54 -0400455 Warning: There are no sanity checking to commands
456 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800457
kelvin8ec71442015-01-15 16:57:00 -0800458 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400459 try:
Jon Halla495f562016-05-16 18:03:26 -0700460 # Try to reconnect if disconnected from cli
461 self.handle.sendline( "" )
462 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
463 if i == 1:
464 main.log.error( self.name + ": onos cli session closed. ")
465 if self.onosIp:
466 main.log.warn( "Trying to reconnect " + self.onosIp )
467 reconnectResult = self.startOnosCli( self.onosIp )
468 if reconnectResult:
469 main.log.info( self.name + ": onos cli session reconnected." )
470 else:
471 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700472 if noExit:
473 return None
474 else:
475 main.cleanup()
476 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700477 else:
478 main.cleanup()
479 main.exit()
480 if i == 2:
481 self.handle.sendline( "" )
482 self.handle.expect( "onos>" )
483
Jon Hall14a03b52016-05-11 12:07:30 -0700484 if debug:
485 # NOTE: This adds and average of .4 seconds per call
486 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700487 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800488 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800489 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800490 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800491 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800492 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
493 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700494 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700495 main.log.debug( self.name + ": Raw output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
498 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800499 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800500 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700501 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700502 main.log.debug( self.name + ": ansiEscape output" )
503 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700504
kelvin-onlabfb521662015-02-27 09:52:40 -0800505 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800506 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700508 main.log.debug( self.name + ": Removed extra returns " +
509 "from output" )
510 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700511
512 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800513 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700515 main.log.debug( self.name + ": parsed and stripped output" )
516 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517
Jon Hall63604932015-02-26 17:09:50 -0800518 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700519 output = response.split( cmdStr.strip(), 1 )
520 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700521 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800524 output = output[1].strip()
525 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800526 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800527 return output
GlennRCed771242016-01-13 17:02:47 -0800528 except pexpect.TIMEOUT:
529 main.log.error( self.name + ":ONOS timeout" )
530 if debug:
531 main.log.debug( self.handle.before )
532 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 except IndexError:
534 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700535 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700536 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800537 except TypeError:
538 main.log.exception( self.name + ": Object not as expected" )
539 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400540 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800541 main.log.error( self.name + ": EOF exception found" )
542 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700543 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700544 return None
545 else:
546 main.cleanup()
547 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800548 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800549 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700550 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700551 return None
552 else:
553 main.cleanup()
554 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400555
kelvin8ec71442015-01-15 16:57:00 -0800556 # IMPORTANT NOTE:
557 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 # the cli command changing 'a:b' with 'aB'.
559 # Ex ) onos:topology > onosTopology
560 # onos:links > onosLinks
561 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800562
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800564 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 Adds a new cluster node by ID and address information.
566 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 * nodeId
568 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800570 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800571 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 cmdStr = "add-node " + str( nodeId ) + " " +\
574 str( ONOSIp ) + " " + str( tcpPort )
575 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700576 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800577 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800578 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800579 main.log.error( "Error in adding node" )
580 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800581 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800585 except AssertionError:
586 main.log.exception( "" )
587 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800588 except TypeError:
589 main.log.exception( self.name + ": Object not as expected" )
590 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400594 main.cleanup()
595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800597 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400598 main.cleanup()
599 main.exit()
600
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800602 """
andrewonlab86dc3082014-10-13 18:18:38 -0400603 Removes a cluster by ID
604 Issues command: 'remove-node [<node-id>]'
605 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800607 """
andrewonlab86dc3082014-10-13 18:18:38 -0400608 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400609
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700611 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700612 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800613 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700614 if re.search( "Error", handle ):
615 main.log.error( "Error in removing node" )
616 main.log.error( handle )
617 return main.FALSE
618 else:
619 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800620 except AssertionError:
621 main.log.exception( "" )
622 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800623 except TypeError:
624 main.log.exception( self.name + ": Object not as expected" )
625 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400626 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800627 main.log.error( self.name + ": EOF exception found" )
628 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400629 main.cleanup()
630 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800631 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800632 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400633 main.cleanup()
634 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400635
Jon Hall61282e32015-03-19 11:34:11 -0700636 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800637 """
andrewonlab7c211572014-10-15 16:45:20 -0400638 List the nodes currently visible
639 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700640 Optional argument:
641 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800642 """
andrewonlab7c211572014-10-15 16:45:20 -0400643 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700644 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700645 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700646 cmdStr += " -j"
647 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700648 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800649 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700650 return output
Jon Hallc6793552016-01-19 14:18:37 -0800651 except AssertionError:
652 main.log.exception( "" )
653 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800654 except TypeError:
655 main.log.exception( self.name + ": Object not as expected" )
656 return None
andrewonlab7c211572014-10-15 16:45:20 -0400657 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800658 main.log.error( self.name + ": EOF exception found" )
659 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400660 main.cleanup()
661 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800662 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800663 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400664 main.cleanup()
665 main.exit()
666
kelvin8ec71442015-01-15 16:57:00 -0800667 def topology( self ):
668 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700669 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700670 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700671 Return:
672 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800673 """
andrewonlab95ce8322014-10-13 14:12:04 -0400674 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700675 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800677 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700678 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400679 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800680 except AssertionError:
681 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800682 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800683 except TypeError:
684 main.log.exception( self.name + ": Object not as expected" )
685 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400686 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800687 main.log.error( self.name + ": EOF exception found" )
688 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400689 main.cleanup()
690 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800691 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800692 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400693 main.cleanup()
694 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800695
jenkins7ead5a82015-03-13 10:28:21 -0700696 def deviceRemove( self, deviceId ):
697 """
698 Removes particular device from storage
699
700 TODO: refactor this function
701 """
702 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700703 cmdStr = "device-remove " + str( deviceId )
704 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800705 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 if re.search( "Error", handle ):
707 main.log.error( "Error in removing device" )
708 main.log.error( handle )
709 return main.FALSE
710 else:
711 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800712 except AssertionError:
713 main.log.exception( "" )
714 return None
jenkins7ead5a82015-03-13 10:28:21 -0700715 except TypeError:
716 main.log.exception( self.name + ": Object not as expected" )
717 return None
718 except pexpect.EOF:
719 main.log.error( self.name + ": EOF exception found" )
720 main.log.error( self.name + ": " + self.handle.before )
721 main.cleanup()
722 main.exit()
723 except Exception:
724 main.log.exception( self.name + ": Uncaught exception!" )
725 main.cleanup()
726 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700727
kelvin-onlabd3b64892015-01-20 13:26:24 -0800728 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800729 """
Jon Hall7b02d952014-10-17 20:14:54 -0400730 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400731 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800733 """
andrewonlab86dc3082014-10-13 18:18:38 -0400734 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700737 cmdStr += " -j"
738 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800739 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700740 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800741 except AssertionError:
742 main.log.exception( "" )
743 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800744 except TypeError:
745 main.log.exception( self.name + ": Object not as expected" )
746 return None
andrewonlab7c211572014-10-15 16:45:20 -0400747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400750 main.cleanup()
751 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800752 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800753 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400754 main.cleanup()
755 main.exit()
756
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800758 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800759 This balances the devices across all controllers
760 by issuing command: 'onos> onos:balance-masters'
761 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800762 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800763 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700765 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800766 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700767 if re.search( "Error", handle ):
768 main.log.error( "Error in balancing masters" )
769 main.log.error( handle )
770 return main.FALSE
771 else:
772 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800773 except AssertionError:
774 main.log.exception( "" )
775 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800776 except TypeError:
777 main.log.exception( self.name + ": Object not as expected" )
778 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800779 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800780 main.log.error( self.name + ": EOF exception found" )
781 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800782 main.cleanup()
783 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800784 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800785 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800786 main.cleanup()
787 main.exit()
788
Jon Hallc6793552016-01-19 14:18:37 -0800789 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700790 """
791 Returns the output of the masters command.
792 Optional argument:
793 * jsonFormat - boolean indicating if you want output in json
794 """
795 try:
796 cmdStr = "onos:masters"
797 if jsonFormat:
798 cmdStr += " -j"
799 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700800 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800801 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700802 return output
Jon Hallc6793552016-01-19 14:18:37 -0800803 except AssertionError:
804 main.log.exception( "" )
805 return None
acsmars24950022015-07-30 18:00:43 -0700806 except TypeError:
807 main.log.exception( self.name + ": Object not as expected" )
808 return None
809 except pexpect.EOF:
810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
812 main.cleanup()
813 main.exit()
814 except Exception:
815 main.log.exception( self.name + ": Uncaught exception!" )
816 main.cleanup()
817 main.exit()
818
Jon Hallc6793552016-01-19 14:18:37 -0800819 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700820 """
821 Uses the master command to check that the devices' leadership
822 is evenly divided
823
824 Dependencies: checkMasters() and summary()
825
Jon Hall6509dbf2016-06-21 17:01:17 -0700826 Returns main.TRUE if the devices are balanced
827 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700828 Exits on Exception
829 Returns None on TypeError
830 """
831 try:
Jon Hallc6793552016-01-19 14:18:37 -0800832 summaryOutput = self.summary()
833 totalDevices = json.loads( summaryOutput )[ "devices" ]
834 except ( TypeError, ValueError ):
835 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
836 return None
837 try:
acsmars24950022015-07-30 18:00:43 -0700838 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800839 mastersOutput = self.checkMasters()
840 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700841 first = masters[ 0 ][ "size" ]
842 for master in masters:
843 totalOwnedDevices += master[ "size" ]
844 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
845 main.log.error( "Mastership not balanced" )
846 main.log.info( "\n" + self.checkMasters( False ) )
847 return main.FALSE
848 main.log.info( "Mastership balanced between " \
849 + str( len(masters) ) + " masters" )
850 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800851 except ( TypeError, ValueError ):
852 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700853 return None
854 except pexpect.EOF:
855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
857 main.cleanup()
858 main.exit()
859 except Exception:
860 main.log.exception( self.name + ": Uncaught exception!" )
861 main.cleanup()
862 main.exit()
863
YPZhangfebf7302016-05-24 16:45:56 -0700864 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800865 """
Jon Halle8217482014-10-17 13:49:14 -0400866 Lists all core links
867 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800869 """
Jon Halle8217482014-10-17 13:49:14 -0400870 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700871 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700873 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700874 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800875 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800877 except AssertionError:
878 main.log.exception( "" )
879 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800880 except TypeError:
881 main.log.exception( self.name + ": Object not as expected" )
882 return None
Jon Halle8217482014-10-17 13:49:14 -0400883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800884 main.log.error( self.name + ": EOF exception found" )
885 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400886 main.cleanup()
887 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800888 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800889 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400890 main.cleanup()
891 main.exit()
892
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800894 """
Jon Halle8217482014-10-17 13:49:14 -0400895 Lists all ports
896 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700902 cmdStr += " -j"
903 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800904 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700905 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800906 except AssertionError:
907 main.log.exception( "" )
908 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800909 except TypeError:
910 main.log.exception( self.name + ": Object not as expected" )
911 return None
Jon Halle8217482014-10-17 13:49:14 -0400912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800913 main.log.error( self.name + ": EOF exception found" )
914 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400915 main.cleanup()
916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800918 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400919 main.cleanup()
920 main.exit()
921
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800923 """
Jon Hall983a1702014-10-28 18:44:22 -0400924 Lists all devices and the controllers with roles assigned to them
925 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800927 """
andrewonlab7c211572014-10-15 16:45:20 -0400928 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700931 cmdStr += " -j"
932 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800933 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800935 except AssertionError:
936 main.log.exception( "" )
937 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800938 except TypeError:
939 main.log.exception( self.name + ": Object not as expected" )
940 return None
Jon Hall983a1702014-10-28 18:44:22 -0400941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400944 main.cleanup()
945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800947 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400948 main.cleanup()
949 main.exit()
950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800952 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800953 Given the a string containing the json representation of the "roles"
954 cli command and a partial or whole device id, returns a json object
955 containing the roles output for the first device whose id contains
956 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400957
958 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800959 A dict of the role assignments for the given device or
960 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800961 """
Jon Hall983a1702014-10-28 18:44:22 -0400962 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400964 return None
965 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 rawRoles = self.roles()
967 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800968 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800970 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400972 return device
973 return None
Jon Hallc6793552016-01-19 14:18:37 -0800974 except ( TypeError, ValueError ):
975 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800976 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800978 main.log.error( self.name + ": EOF exception found" )
979 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400980 main.cleanup()
981 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800983 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400984 main.cleanup()
985 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001009 main.cleanup()
1010 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001011 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001012 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001013 main.cleanup()
1014 main.exit()
1015
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001018 Returns string of paths, and the cost.
1019 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001020 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001021 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001022 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1023 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001024 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001025 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001026 main.log.error( "Error in getting paths" )
1027 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001028 else:
kelvin8ec71442015-01-15 16:57:00 -08001029 path = handle.split( ";" )[ 0 ]
1030 cost = handle.split( ";" )[ 1 ]
1031 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001032 except AssertionError:
1033 main.log.exception( "" )
1034 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001035 except TypeError:
1036 main.log.exception( self.name + ": Object not as expected" )
1037 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001038 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001039 main.log.error( self.name + ": EOF exception found" )
1040 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001041 main.cleanup()
1042 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001043 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001044 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001045 main.cleanup()
1046 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001047
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001049 """
Jon Hallffb386d2014-11-21 13:43:38 -08001050 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001053 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001054 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001055 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001056 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001057 cmdStr += " -j"
1058 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001059 if handle:
1060 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001061 # TODO: Maybe make this less hardcoded
1062 # ConsistentMap Exceptions
1063 assert "org.onosproject.store.service" not in handle
1064 # Node not leader
1065 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001066 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001067 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001068 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001069 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001070 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001071 except TypeError:
1072 main.log.exception( self.name + ": Object not as expected" )
1073 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001074 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001075 main.log.error( self.name + ": EOF exception found" )
1076 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001077 main.cleanup()
1078 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001079 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001080 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 main.cleanup()
1082 main.exit()
1083
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001085 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001087
Jon Hallefbd9792015-03-05 16:11:36 -08001088 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001089 partial mac address
1090
Jon Hall42db6dc2014-10-24 19:03:48 -04001091 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001092 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001093 try:
kelvin8ec71442015-01-15 16:57:00 -08001094 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001095 return None
1096 else:
1097 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 rawHosts = self.hosts()
1099 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001100 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001102 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001103 if not host:
1104 pass
1105 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 return host
1107 return None
Jon Hallc6793552016-01-19 14:18:37 -08001108 except ( TypeError, ValueError ):
1109 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001110 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001111 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001112 main.log.error( self.name + ": EOF exception found" )
1113 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001114 main.cleanup()
1115 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001116 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001117 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001118 main.cleanup()
1119 main.exit()
1120
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001122 """
1123 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001125
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128 IMPORTANT:
1129 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001130 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131 Furthermore, it assumes that value of VLAN is '-1'
1132 Description:
kelvin8ec71442015-01-15 16:57:00 -08001133 Converts mininet hosts ( h1, h2, h3... ) into
1134 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1135 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001136 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001140 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 hostHex = hex( int( host ) ).zfill( 12 )
1142 hostHex = str( hostHex ).replace( 'x', '0' )
1143 i = iter( str( hostHex ) )
1144 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1145 hostHex = hostHex + "/-1"
1146 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001147
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001149
Jon Halld4d4b372015-01-28 16:02:41 -08001150 except TypeError:
1151 main.log.exception( self.name + ": Object not as expected" )
1152 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001154 main.log.error( self.name + ": EOF exception found" )
1155 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001156 main.cleanup()
1157 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001159 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001160 main.cleanup()
1161 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001162
Jeremy Songsterc032f162016-08-04 17:14:49 -07001163 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlabe6745342014-10-17 14:29:13 -04001165 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 * hostIdOne: ONOS host id for host1
1167 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001168 Optional:
1169 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001170 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001171 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001172 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001173 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001174 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001175 Returns:
1176 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001177 """
andrewonlabe6745342014-10-17 14:29:13 -04001178 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001179 cmdStr = "add-host-intent "
1180 if vlanId:
1181 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001182 if setVlan:
1183 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001184 if encap:
1185 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001186 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001188 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001189 if re.search( "Error", handle ):
1190 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001191 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001192 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001193 else:
1194 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001195 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1196 match = re.search('id=0x([\da-f]+),', handle)
1197 if match:
1198 return match.group()[3:-1]
1199 else:
1200 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001201 main.log.debug( "Response from ONOS was: " +
1202 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001203 return None
Jon Hallc6793552016-01-19 14:18:37 -08001204 except AssertionError:
1205 main.log.exception( "" )
1206 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001207 except TypeError:
1208 main.log.exception( self.name + ": Object not as expected" )
1209 return None
andrewonlabe6745342014-10-17 14:29:13 -04001210 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001211 main.log.error( self.name + ": EOF exception found" )
1212 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001213 main.cleanup()
1214 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001215 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001216 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001217 main.cleanup()
1218 main.exit()
1219
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001221 """
andrewonlab7b31d232014-10-24 13:31:47 -04001222 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 * ingressDevice: device id of ingress device
1224 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001225 Optional:
1226 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 Description:
1228 Adds an optical intent by specifying an ingress and egress device
1229 Returns:
1230 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001231 """
andrewonlab7b31d232014-10-24 13:31:47 -04001232 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1234 " " + str( egressDevice )
1235 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001236 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001237 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001238 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001239 main.log.error( "Error in adding Optical intent" )
1240 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001241 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001242 main.log.info( "Optical intent installed between " +
1243 str( ingressDevice ) + " and " +
1244 str( egressDevice ) )
1245 match = re.search('id=0x([\da-f]+),', handle)
1246 if match:
1247 return match.group()[3:-1]
1248 else:
1249 main.log.error( "Error, intent ID not found" )
1250 return None
Jon Hallc6793552016-01-19 14:18:37 -08001251 except AssertionError:
1252 main.log.exception( "" )
1253 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001254 except TypeError:
1255 main.log.exception( self.name + ": Object not as expected" )
1256 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001258 main.log.error( self.name + ": EOF exception found" )
1259 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001260 main.cleanup()
1261 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001262 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001263 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001264 main.cleanup()
1265 main.exit()
1266
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001268 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 ingressDevice,
1270 egressDevice,
1271 portIngress="",
1272 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001273 ethType="",
1274 ethSrc="",
1275 ethDst="",
1276 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001278 ipProto="",
1279 ipSrc="",
1280 ipDst="",
1281 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001282 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001283 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001284 setVlan="",
1285 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001286 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001287 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 * ingressDevice: device id of ingress device
1289 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001290 Optional:
1291 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001292 * ethSrc: specify ethSrc ( i.e. src mac addr )
1293 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001294 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001296 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001297 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001298 * ipSrc: specify ip source address
1299 * ipDst: specify ip destination address
1300 * tcpSrc: specify tcp source port
1301 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001302 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001303 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001304 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001305 Description:
kelvin8ec71442015-01-15 16:57:00 -08001306 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001307 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001308 Returns:
1309 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001310
Jon Halle3f39ff2015-01-13 11:50:53 -08001311 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001312 options developers provide for point-to-point
1313 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001314 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001315 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001316 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001317
Jeremy Songsterff553672016-05-12 17:06:23 -07001318 if ethType:
1319 cmd += " --ethType " + str( ethType )
1320 if ethSrc:
1321 cmd += " --ethSrc " + str( ethSrc )
1322 if ethDst:
1323 cmd += " --ethDst " + str( ethDst )
1324 if bandwidth:
1325 cmd += " --bandwidth " + str( bandwidth )
1326 if lambdaAlloc:
1327 cmd += " --lambda "
1328 if ipProto:
1329 cmd += " --ipProto " + str( ipProto )
1330 if ipSrc:
1331 cmd += " --ipSrc " + str( ipSrc )
1332 if ipDst:
1333 cmd += " --ipDst " + str( ipDst )
1334 if tcpSrc:
1335 cmd += " --tcpSrc " + str( tcpSrc )
1336 if tcpDst:
1337 cmd += " --tcpDst " + str( tcpDst )
1338 if vlanId:
1339 cmd += " -v " + str( vlanId )
1340 if setVlan:
1341 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001342 if encap:
1343 cmd += " --encapsulation " + str( encap )
andrewonlab289e4b72014-10-21 21:24:18 -04001344
kelvin8ec71442015-01-15 16:57:00 -08001345 # Check whether the user appended the port
1346 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 if "/" in ingressDevice:
1348 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001349 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001350 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001351 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001352 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001353 # Would it make sense to throw an exception and exit
1354 # the test?
1355 return None
andrewonlab36af3822014-11-18 17:48:18 -05001356
kelvin8ec71442015-01-15 16:57:00 -08001357 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 str( ingressDevice ) + "/" +\
1359 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001360
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 if "/" in egressDevice:
1362 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001363 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001364 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001365 main.log.error( "You must specify the egress port" )
1366 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001367
kelvin8ec71442015-01-15 16:57:00 -08001368 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 str( egressDevice ) + "/" +\
1370 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001371
kelvin-onlab898a6c62015-01-16 14:13:53 -08001372 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001373 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001374 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001375 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001376 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001377 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001378 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001379 # TODO: print out all the options in this message?
1380 main.log.info( "Point-to-point intent installed between " +
1381 str( ingressDevice ) + " and " +
1382 str( egressDevice ) )
1383 match = re.search('id=0x([\da-f]+),', handle)
1384 if match:
1385 return match.group()[3:-1]
1386 else:
1387 main.log.error( "Error, intent ID not found" )
1388 return None
Jon Hallc6793552016-01-19 14:18:37 -08001389 except AssertionError:
1390 main.log.exception( "" )
1391 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001392 except TypeError:
1393 main.log.exception( self.name + ": Object not as expected" )
1394 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001395 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001396 main.log.error( self.name + ": EOF exception found" )
1397 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001398 main.cleanup()
1399 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001400 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001401 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001402 main.cleanup()
1403 main.exit()
1404
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001406 self,
shahshreyac2f97072015-03-19 17:04:29 -07001407 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001409 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001411 ethType="",
1412 ethSrc="",
1413 ethDst="",
1414 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001415 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001416 ipProto="",
1417 ipSrc="",
1418 ipDst="",
1419 tcpSrc="",
1420 tcpDst="",
1421 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001422 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001423 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001424 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001425 partial=False,
1426 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001427 """
shahshreyad0c80432014-12-04 16:56:05 -08001428 Note:
shahshreya70622b12015-03-19 17:19:00 -07001429 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001430 is same. That is, all ingress devices include port numbers
1431 with a "/" or all ingress devices could specify device
1432 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001433 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001434 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001435 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001437 Optional:
1438 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001439 * ethSrc: specify ethSrc ( i.e. src mac addr )
1440 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001441 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001443 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001444 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001445 * ipSrc: specify ip source address
1446 * ipDst: specify ip destination address
1447 * tcpSrc: specify tcp source port
1448 * tcpDst: specify tcp destination port
1449 * setEthSrc: action to Rewrite Source MAC Address
1450 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001451 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001452 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001453 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001454 Description:
kelvin8ec71442015-01-15 16:57:00 -08001455 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001456 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001457 Returns:
1458 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001459
Jon Halle3f39ff2015-01-13 11:50:53 -08001460 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001461 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001462 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001463 """
shahshreyad0c80432014-12-04 16:56:05 -08001464 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001465 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001466
Jeremy Songsterff553672016-05-12 17:06:23 -07001467 if ethType:
1468 cmd += " --ethType " + str( ethType )
1469 if ethSrc:
1470 cmd += " --ethSrc " + str( ethSrc )
1471 if ethDst:
1472 cmd += " --ethDst " + str( ethDst )
1473 if bandwidth:
1474 cmd += " --bandwidth " + str( bandwidth )
1475 if lambdaAlloc:
1476 cmd += " --lambda "
1477 if ipProto:
1478 cmd += " --ipProto " + str( ipProto )
1479 if ipSrc:
1480 cmd += " --ipSrc " + str( ipSrc )
1481 if ipDst:
1482 cmd += " --ipDst " + str( ipDst )
1483 if tcpSrc:
1484 cmd += " --tcpSrc " + str( tcpSrc )
1485 if tcpDst:
1486 cmd += " --tcpDst " + str( tcpDst )
1487 if setEthSrc:
1488 cmd += " --setEthSrc " + str( setEthSrc )
1489 if setEthDst:
1490 cmd += " --setEthDst " + str( setEthDst )
1491 if vlanId:
1492 cmd += " -v " + str( vlanId )
1493 if setVlan:
1494 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001495 if partial:
1496 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001497 if encap:
1498 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001499
kelvin8ec71442015-01-15 16:57:00 -08001500 # Check whether the user appended the port
1501 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001502
1503 if portIngressList is None:
1504 for ingressDevice in ingressDeviceList:
1505 if "/" in ingressDevice:
1506 cmd += " " + str( ingressDevice )
1507 else:
1508 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001509 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001510 # TODO: perhaps more meaningful return
1511 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001512 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001513 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001514 for ingressDevice, portIngress in zip( ingressDeviceList,
1515 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001516 cmd += " " + \
1517 str( ingressDevice ) + "/" +\
1518 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001519 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001520 main.log.error( "Device list and port list does not " +
1521 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001522 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 if "/" in egressDevice:
1524 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001525 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001527 main.log.error( "You must specify " +
1528 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001529 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001530
kelvin8ec71442015-01-15 16:57:00 -08001531 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 str( egressDevice ) + "/" +\
1533 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001534 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001535 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001536 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001537 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001538 main.log.error( "Error in adding multipoint-to-singlepoint " +
1539 "intent" )
1540 return None
shahshreyad0c80432014-12-04 16:56:05 -08001541 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001542 match = re.search('id=0x([\da-f]+),', handle)
1543 if match:
1544 return match.group()[3:-1]
1545 else:
1546 main.log.error( "Error, intent ID not found" )
1547 return None
Jon Hallc6793552016-01-19 14:18:37 -08001548 except AssertionError:
1549 main.log.exception( "" )
1550 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001551 except TypeError:
1552 main.log.exception( self.name + ": Object not as expected" )
1553 return None
1554 except pexpect.EOF:
1555 main.log.error( self.name + ": EOF exception found" )
1556 main.log.error( self.name + ": " + self.handle.before )
1557 main.cleanup()
1558 main.exit()
1559 except Exception:
1560 main.log.exception( self.name + ": Uncaught exception!" )
1561 main.cleanup()
1562 main.exit()
1563
1564 def addSinglepointToMultipointIntent(
1565 self,
1566 ingressDevice,
1567 egressDeviceList,
1568 portIngress="",
1569 portEgressList=None,
1570 ethType="",
1571 ethSrc="",
1572 ethDst="",
1573 bandwidth="",
1574 lambdaAlloc=False,
1575 ipProto="",
1576 ipSrc="",
1577 ipDst="",
1578 tcpSrc="",
1579 tcpDst="",
1580 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001581 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001582 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001583 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001584 partial=False,
1585 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001586 """
1587 Note:
1588 This function assumes the format of all egress devices
1589 is same. That is, all egress devices include port numbers
1590 with a "/" or all egress devices could specify device
1591 ids and port numbers seperately.
1592 Required:
1593 * EgressDeviceList: List of device ids of egress device
1594 ( Atleast 2 eress devices required in the list )
1595 * ingressDevice: device id of ingress device
1596 Optional:
1597 * ethType: specify ethType
1598 * ethSrc: specify ethSrc ( i.e. src mac addr )
1599 * ethDst: specify ethDst ( i.e. dst mac addr )
1600 * bandwidth: specify bandwidth capacity of link
1601 * lambdaAlloc: if True, intent will allocate lambda
1602 for the specified intent
1603 * ipProto: specify ip protocol
1604 * ipSrc: specify ip source address
1605 * ipDst: specify ip destination address
1606 * tcpSrc: specify tcp source port
1607 * tcpDst: specify tcp destination port
1608 * setEthSrc: action to Rewrite Source MAC Address
1609 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001610 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001611 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001612 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001613 Description:
1614 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1615 specifying device id's and optional fields
1616 Returns:
1617 A string of the intent id or None on error
1618
1619 NOTE: This function may change depending on the
1620 options developers provide for singlepoint-to-multipoint
1621 intent via cli
1622 """
1623 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001624 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001625
Jeremy Songsterff553672016-05-12 17:06:23 -07001626 if ethType:
1627 cmd += " --ethType " + str( ethType )
1628 if ethSrc:
1629 cmd += " --ethSrc " + str( ethSrc )
1630 if ethDst:
1631 cmd += " --ethDst " + str( ethDst )
1632 if bandwidth:
1633 cmd += " --bandwidth " + str( bandwidth )
1634 if lambdaAlloc:
1635 cmd += " --lambda "
1636 if ipProto:
1637 cmd += " --ipProto " + str( ipProto )
1638 if ipSrc:
1639 cmd += " --ipSrc " + str( ipSrc )
1640 if ipDst:
1641 cmd += " --ipDst " + str( ipDst )
1642 if tcpSrc:
1643 cmd += " --tcpSrc " + str( tcpSrc )
1644 if tcpDst:
1645 cmd += " --tcpDst " + str( tcpDst )
1646 if setEthSrc:
1647 cmd += " --setEthSrc " + str( setEthSrc )
1648 if setEthDst:
1649 cmd += " --setEthDst " + str( setEthDst )
1650 if vlanId:
1651 cmd += " -v " + str( vlanId )
1652 if setVlan:
1653 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001654 if partial:
1655 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001656 if encap:
1657 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001658
1659 # Check whether the user appended the port
1660 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001661
kelvin-onlabb9408212015-04-01 13:34:04 -07001662 if "/" in ingressDevice:
1663 cmd += " " + str( ingressDevice )
1664 else:
1665 if not portIngress:
1666 main.log.error( "You must specify " +
1667 "the Ingress port" )
1668 return main.FALSE
1669
1670 cmd += " " +\
1671 str( ingressDevice ) + "/" +\
1672 str( portIngress )
1673
1674 if portEgressList is None:
1675 for egressDevice in egressDeviceList:
1676 if "/" in egressDevice:
1677 cmd += " " + str( egressDevice )
1678 else:
1679 main.log.error( "You must specify " +
1680 "the egress port" )
1681 # TODO: perhaps more meaningful return
1682 return main.FALSE
1683 else:
1684 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001685 for egressDevice, portEgress in zip( egressDeviceList,
1686 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001687 cmd += " " + \
1688 str( egressDevice ) + "/" +\
1689 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001690 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001691 main.log.error( "Device list and port list does not " +
1692 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001693 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001694 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001695 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001696 # If error, return error message
1697 if re.search( "Error", handle ):
1698 main.log.error( "Error in adding singlepoint-to-multipoint " +
1699 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001700 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001701 else:
1702 match = re.search('id=0x([\da-f]+),', handle)
1703 if match:
1704 return match.group()[3:-1]
1705 else:
1706 main.log.error( "Error, intent ID not found" )
1707 return None
Jon Hallc6793552016-01-19 14:18:37 -08001708 except AssertionError:
1709 main.log.exception( "" )
1710 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001711 except TypeError:
1712 main.log.exception( self.name + ": Object not as expected" )
1713 return None
shahshreyad0c80432014-12-04 16:56:05 -08001714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001717 main.cleanup()
1718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001720 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001721 main.cleanup()
1722 main.exit()
1723
Hari Krishna9e232602015-04-13 17:29:08 -07001724 def addMplsIntent(
1725 self,
1726 ingressDevice,
1727 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001728 ingressPort="",
1729 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001730 ethType="",
1731 ethSrc="",
1732 ethDst="",
1733 bandwidth="",
1734 lambdaAlloc=False,
1735 ipProto="",
1736 ipSrc="",
1737 ipDst="",
1738 tcpSrc="",
1739 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001740 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001741 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001742 priority=""):
1743 """
1744 Required:
1745 * ingressDevice: device id of ingress device
1746 * egressDevice: device id of egress device
1747 Optional:
1748 * ethType: specify ethType
1749 * ethSrc: specify ethSrc ( i.e. src mac addr )
1750 * ethDst: specify ethDst ( i.e. dst mac addr )
1751 * bandwidth: specify bandwidth capacity of link
1752 * lambdaAlloc: if True, intent will allocate lambda
1753 for the specified intent
1754 * ipProto: specify ip protocol
1755 * ipSrc: specify ip source address
1756 * ipDst: specify ip destination address
1757 * tcpSrc: specify tcp source port
1758 * tcpDst: specify tcp destination port
1759 * ingressLabel: Ingress MPLS label
1760 * egressLabel: Egress MPLS label
1761 Description:
1762 Adds MPLS intent by
1763 specifying device id's and optional fields
1764 Returns:
1765 A string of the intent id or None on error
1766
1767 NOTE: This function may change depending on the
1768 options developers provide for MPLS
1769 intent via cli
1770 """
1771 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001772 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001773
Jeremy Songsterff553672016-05-12 17:06:23 -07001774 if ethType:
1775 cmd += " --ethType " + str( ethType )
1776 if ethSrc:
1777 cmd += " --ethSrc " + str( ethSrc )
1778 if ethDst:
1779 cmd += " --ethDst " + str( ethDst )
1780 if bandwidth:
1781 cmd += " --bandwidth " + str( bandwidth )
1782 if lambdaAlloc:
1783 cmd += " --lambda "
1784 if ipProto:
1785 cmd += " --ipProto " + str( ipProto )
1786 if ipSrc:
1787 cmd += " --ipSrc " + str( ipSrc )
1788 if ipDst:
1789 cmd += " --ipDst " + str( ipDst )
1790 if tcpSrc:
1791 cmd += " --tcpSrc " + str( tcpSrc )
1792 if tcpDst:
1793 cmd += " --tcpDst " + str( tcpDst )
1794 if ingressLabel:
1795 cmd += " --ingressLabel " + str( ingressLabel )
1796 if egressLabel:
1797 cmd += " --egressLabel " + str( egressLabel )
1798 if priority:
1799 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001800
1801 # Check whether the user appended the port
1802 # or provided it as an input
1803 if "/" in ingressDevice:
1804 cmd += " " + str( ingressDevice )
1805 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001806 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001807 main.log.error( "You must specify the ingress port" )
1808 return None
1809
1810 cmd += " " + \
1811 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001812 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001813
1814 if "/" in egressDevice:
1815 cmd += " " + str( egressDevice )
1816 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001817 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001818 main.log.error( "You must specify the egress port" )
1819 return None
1820
1821 cmd += " " +\
1822 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001823 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001824
1825 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001826 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001827 # If error, return error message
1828 if re.search( "Error", handle ):
1829 main.log.error( "Error in adding mpls intent" )
1830 return None
1831 else:
1832 # TODO: print out all the options in this message?
1833 main.log.info( "MPLS intent installed between " +
1834 str( ingressDevice ) + " and " +
1835 str( egressDevice ) )
1836 match = re.search('id=0x([\da-f]+),', handle)
1837 if match:
1838 return match.group()[3:-1]
1839 else:
1840 main.log.error( "Error, intent ID not found" )
1841 return None
Jon Hallc6793552016-01-19 14:18:37 -08001842 except AssertionError:
1843 main.log.exception( "" )
1844 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001845 except TypeError:
1846 main.log.exception( self.name + ": Object not as expected" )
1847 return None
1848 except pexpect.EOF:
1849 main.log.error( self.name + ": EOF exception found" )
1850 main.log.error( self.name + ": " + self.handle.before )
1851 main.cleanup()
1852 main.exit()
1853 except Exception:
1854 main.log.exception( self.name + ": Uncaught exception!" )
1855 main.cleanup()
1856 main.exit()
1857
Jon Hallefbd9792015-03-05 16:11:36 -08001858 def removeIntent( self, intentId, app='org.onosproject.cli',
1859 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001860 """
shahshreya1c818fc2015-02-26 13:44:08 -08001861 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001862 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001863 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001864 -p or --purge: Purge the intent from the store after removal
1865
Jon Halle3f39ff2015-01-13 11:50:53 -08001866 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001867 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001868 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001869 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001870 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001871 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001872 if purge:
1873 cmdStr += " -p"
1874 if sync:
1875 cmdStr += " -s"
1876
1877 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001879 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001880 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001881 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001882 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001883 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001884 # TODO: Should this be main.TRUE
1885 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001886 except AssertionError:
1887 main.log.exception( "" )
1888 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001889 except TypeError:
1890 main.log.exception( self.name + ": Object not as expected" )
1891 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001892 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001893 main.log.error( self.name + ": EOF exception found" )
1894 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001895 main.cleanup()
1896 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001898 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001899 main.cleanup()
1900 main.exit()
1901
YPZhangfebf7302016-05-24 16:45:56 -07001902 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001903 """
1904 Description:
1905 Remove all the intents
1906 Optional args:-
1907 -s or --sync: Waits for the removal before returning
1908 -p or --purge: Purge the intent from the store after removal
1909 Returns:
1910 Returns main.TRUE if all intents are removed, otherwise returns
1911 main.FALSE; Returns None for exception
1912 """
1913 try:
1914 cmdStr = "remove-intent"
1915 if purge:
1916 cmdStr += " -p"
1917 if sync:
1918 cmdStr += " -s"
1919
1920 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001921 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001922 assert "Command not found:" not in handle, handle
1923 if re.search( "Error", handle ):
1924 main.log.error( "Error in removing intent" )
1925 return main.FALSE
1926 else:
1927 return main.TRUE
1928 except AssertionError:
1929 main.log.exception( "" )
1930 return None
1931 except TypeError:
1932 main.log.exception( self.name + ": Object not as expected" )
1933 return None
1934 except pexpect.EOF:
1935 main.log.error( self.name + ": EOF exception found" )
1936 main.log.error( self.name + ": " + self.handle.before )
1937 main.cleanup()
1938 main.exit()
1939 except Exception:
1940 main.log.exception( self.name + ": Uncaught exception!" )
1941 main.cleanup()
1942 main.exit()
1943
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001944 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001945 """
1946 Purges all WITHDRAWN Intents
1947 """
1948 try:
1949 cmdStr = "purge-intents"
1950 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001951 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001952 if re.search( "Error", handle ):
1953 main.log.error( "Error in purging intents" )
1954 return main.FALSE
1955 else:
1956 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001957 except AssertionError:
1958 main.log.exception( "" )
1959 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001960 except TypeError:
1961 main.log.exception( self.name + ": Object not as expected" )
1962 return None
1963 except pexpect.EOF:
1964 main.log.error( self.name + ": EOF exception found" )
1965 main.log.error( self.name + ": " + self.handle.before )
1966 main.cleanup()
1967 main.exit()
1968 except Exception:
1969 main.log.exception( self.name + ": Uncaught exception!" )
1970 main.cleanup()
1971 main.exit()
1972
kelvin-onlabd3b64892015-01-20 13:26:24 -08001973 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001974 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001975 NOTE: This method should be used after installing application:
1976 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001977 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001978 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001979 Description:
1980 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001981 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001983 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001985 cmdStr += " -j"
1986 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001987 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001988 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001989 except AssertionError:
1990 main.log.exception( "" )
1991 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001992 except TypeError:
1993 main.log.exception( self.name + ": Object not as expected" )
1994 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001995 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001996 main.log.error( self.name + ": EOF exception found" )
1997 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001998 main.cleanup()
1999 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002000 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002001 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002002 main.cleanup()
2003 main.exit()
2004
pingping-lin54b03372015-08-13 14:43:10 -07002005 def ipv4RouteNumber( self ):
2006 """
2007 NOTE: This method should be used after installing application:
2008 onos-app-sdnip
2009 Description:
2010 Obtain the total IPv4 routes number in the system
2011 """
2012 try:
2013 cmdStr = "routes -s -j"
2014 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002015 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002016 jsonResult = json.loads( handle )
2017 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002018 except AssertionError:
2019 main.log.exception( "" )
2020 return None
2021 except ( TypeError, ValueError ):
2022 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002023 return None
2024 except pexpect.EOF:
2025 main.log.error( self.name + ": EOF exception found" )
2026 main.log.error( self.name + ": " + self.handle.before )
2027 main.cleanup()
2028 main.exit()
2029 except Exception:
2030 main.log.exception( self.name + ": Uncaught exception!" )
2031 main.cleanup()
2032 main.exit()
2033
pingping-lin8244a3b2015-09-16 13:36:56 -07002034 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002035 """
andrewonlabe6745342014-10-17 14:29:13 -04002036 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002037 Obtain intents from the ONOS cli.
2038 Optional:
2039 * jsonFormat: Enable output formatting in json, default to True
2040 * summary: Whether only output the intent summary, defaults to False
2041 * type: Only output a certain type of intent. This options is valid
2042 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002043 """
andrewonlabe6745342014-10-17 14:29:13 -04002044 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002045 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002046 if summary:
2047 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002048 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002049 cmdStr += " -j"
2050 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002051 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002052 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002053 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002054 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002055 else:
Jon Hallff566d52016-01-15 14:45:36 -08002056 intentType = ""
2057 # IF we want the summary of a specific intent type
2058 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002059 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002060 if intentType in jsonResult.keys():
2061 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002062 else:
Jon Hallff566d52016-01-15 14:45:36 -08002063 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002064 return handle
2065 else:
2066 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002067 except AssertionError:
2068 main.log.exception( "" )
2069 return None
2070 except ( TypeError, ValueError ):
2071 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002072 return None
2073 except pexpect.EOF:
2074 main.log.error( self.name + ": EOF exception found" )
2075 main.log.error( self.name + ": " + self.handle.before )
2076 main.cleanup()
2077 main.exit()
2078 except Exception:
2079 main.log.exception( self.name + ": Uncaught exception!" )
2080 main.cleanup()
2081 main.exit()
2082
kelvin-onlab54400a92015-02-26 18:05:51 -08002083 def getIntentState(self, intentsId, intentsJson=None):
2084 """
You Wangfdcbfc42016-05-16 12:16:53 -07002085 Description:
2086 Gets intent state. Accepts a single intent ID (string type) or a
2087 list of intent IDs.
2088 Parameters:
2089 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002090 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002091 Returns:
2092 Returns the state (string type) of the ID if a single intent ID is
2093 accepted.
2094 Returns a list of dictionaries if a list of intent IDs is accepted,
2095 and each dictionary maps 'id' to the Intent ID and 'state' to
2096 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002097 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002098 try:
2099 state = "State is Undefined"
2100 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002101 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 else:
Jon Hallc6793552016-01-19 14:18:37 -08002103 rawJson = intentsJson
2104 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002105 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002106 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002107 if intentsId == intent[ 'id' ]:
2108 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002110 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2111 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002112 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002113 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002114 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002115 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002116 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002117 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 if intentsId[ i ] == intents[ 'id' ]:
2119 stateDict[ 'state' ] = intents[ 'state' ]
2120 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002121 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002122 break
Jon Hallefbd9792015-03-05 16:11:36 -08002123 if len( intentsId ) != len( dictList ):
2124 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002125 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002126 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002127 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002128 return None
Jon Hallc6793552016-01-19 14:18:37 -08002129 except ( TypeError, ValueError ):
2130 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002131 return None
2132 except pexpect.EOF:
2133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
2135 main.cleanup()
2136 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002137 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002138 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002139 main.cleanup()
2140 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002141
kelvin-onlabf512e942015-06-08 19:42:59 -07002142 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 """
2144 Description:
2145 Check intents state
2146 Required:
2147 intentsId - List of intents ID to be checked
2148 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002149 expectedState - Check the expected state(s) of each intents
2150 state in the list.
2151 *NOTE: You can pass in a list of expected state,
2152 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002153 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002154 Returns main.TRUE only if all intent are the same as expected states
2155 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002156 """
2157 try:
2158 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002159 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002160 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002161 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002162 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002163 "getting intents state" )
2164 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002165
2166 if isinstance( expectedState, types.StringType ):
2167 for intents in intentsDict:
2168 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002169 main.log.debug( self.name + " : Intent ID - " +
2170 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002171 " actual state = " +
2172 intents.get( 'state' )
2173 + " does not equal expected state = "
2174 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002175 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002176
2177 elif isinstance( expectedState, types.ListType ):
2178 for intents in intentsDict:
2179 if not any( state == intents.get( 'state' ) for state in
2180 expectedState ):
2181 main.log.debug( self.name + " : Intent ID - " +
2182 intents.get( 'id' ) +
2183 " actual state = " +
2184 intents.get( 'state' ) +
2185 " does not equal expected states = "
2186 + str( expectedState ) )
2187 returnValue = main.FALSE
2188
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002189 if returnValue == main.TRUE:
2190 main.log.info( self.name + ": All " +
2191 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002192 " intents are in " + str( expectedState ) +
2193 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002194 return returnValue
2195 except TypeError:
2196 main.log.exception( self.name + ": Object not as expected" )
2197 return None
2198 except pexpect.EOF:
2199 main.log.error( self.name + ": EOF exception found" )
2200 main.log.error( self.name + ": " + self.handle.before )
2201 main.cleanup()
2202 main.exit()
2203 except Exception:
2204 main.log.exception( self.name + ": Uncaught exception!" )
2205 main.cleanup()
2206 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002207
You Wang66518af2016-05-16 15:32:59 -07002208 def compareIntent( self, intentDict ):
2209 """
2210 Description:
2211 Compare the intent ids and states provided in the argument with all intents in ONOS
2212 Return:
2213 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2214 Arguments:
2215 intentDict: a dictionary which maps intent ids to intent states
2216 """
2217 try:
2218 intentsRaw = self.intents()
2219 intentsJson = json.loads( intentsRaw )
2220 intentDictONOS = {}
2221 for intent in intentsJson:
2222 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002223 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002224 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002225 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002226 str( len( intentDict ) ) + " expected and " +
2227 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002228 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002229 for intentID in intentDict.keys():
2230 if not intentID in intentDictONOS.keys():
2231 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2232 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002233 else:
2234 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2235 main.log.debug( self.name + ": intent ID - " + intentID +
2236 " expected state is " + intentDict[ intentID ] +
2237 " but actual state is " + intentDictONOS[ intentID ] )
2238 returnValue = main.FALSE
2239 intentDictONOS.pop( intentID )
2240 if len( intentDictONOS ) > 0:
2241 returnValue = main.FALSE
2242 for intentID in intentDictONOS.keys():
2243 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002244 if returnValue == main.TRUE:
2245 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2246 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002247 except KeyError:
2248 main.log.exception( self.name + ": KeyError exception found" )
2249 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002250 except ( TypeError, ValueError ):
2251 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002252 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002253 except pexpect.EOF:
2254 main.log.error( self.name + ": EOF exception found" )
2255 main.log.error( self.name + ": " + self.handle.before )
2256 main.cleanup()
2257 main.exit()
2258 except Exception:
2259 main.log.exception( self.name + ": Uncaught exception!" )
2260 main.cleanup()
2261 main.exit()
2262
YPZhang14a4aa92016-07-15 13:37:15 -07002263 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002264 """
2265 Description:
2266 Check the number of installed intents.
2267 Optional:
2268 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002269 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002270 Return:
2271 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2272 , otherwise, returns main.FALSE.
2273 """
2274
2275 try:
2276 cmd = "intents -s -j"
2277
2278 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002279 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002280 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002281 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002282 response = json.loads( response )
2283
2284 # get total and installed number, see if they are match
2285 allState = response.get( 'all' )
2286 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002287 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002288 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002289 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002290 return main.FALSE
2291
Jon Hallc6793552016-01-19 14:18:37 -08002292 except ( TypeError, ValueError ):
2293 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002294 return None
2295 except pexpect.EOF:
2296 main.log.error( self.name + ": EOF exception found" )
2297 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002298 if noExit:
2299 return main.FALSE
2300 else:
2301 main.cleanup()
2302 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002303 except Exception:
2304 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002305 if noExit:
2306 return main.FALSE
2307 else:
2308 main.cleanup()
2309 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002310 except pexpect.TIMEOUT:
2311 main.log.error( self.name + ": ONOS timeout" )
2312 return None
GlennRCed771242016-01-13 17:02:47 -08002313
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002314 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002315 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002316 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002317 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002318 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002319 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002320 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002321 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002322 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002323 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002324 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002325 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002326 if noCore:
2327 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002328 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002329 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002330 assert "Command not found:" not in handle, handle
2331 if re.search( "Error:", handle ):
2332 main.log.error( self.name + ": flows() response: " +
2333 str( handle ) )
2334 return handle
2335 except AssertionError:
2336 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002337 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002338 except TypeError:
2339 main.log.exception( self.name + ": Object not as expected" )
2340 return None
Jon Hallc6793552016-01-19 14:18:37 -08002341 except pexpect.TIMEOUT:
2342 main.log.error( self.name + ": ONOS timeout" )
2343 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002344 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002345 main.log.error( self.name + ": EOF exception found" )
2346 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002347 main.cleanup()
2348 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002349 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002350 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002351 main.cleanup()
2352 main.exit()
2353
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002354 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002355 count = self.getTotalFlowsNum( timeout=timeout )
2356 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002357 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002358
YPZhangebf9eb52016-05-12 15:20:24 -07002359 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002360 """
2361 Description:
GlennRCed771242016-01-13 17:02:47 -08002362 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002363 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2364 if the count of those states is 0, which means all current flows
2365 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002366 Optional:
GlennRCed771242016-01-13 17:02:47 -08002367 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002368 Return:
2369 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002370 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002371 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002372 """
2373 try:
GlennRCed771242016-01-13 17:02:47 -08002374 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2375 checkedStates = []
2376 statesCount = [0, 0, 0, 0]
2377 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002378 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002379 if rawFlows:
2380 # if we didn't get flows or flows function return None, we should return
2381 # main.Flase
2382 checkedStates.append( json.loads( rawFlows ) )
2383 else:
2384 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002385 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002386 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002387 try:
2388 statesCount[i] += int( c.get( "flowCount" ) )
2389 except TypeError:
2390 main.log.exception( "Json object not as expected" )
2391 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002392
GlennRCed771242016-01-13 17:02:47 -08002393 # We want to count PENDING_ADD if isPENDING is true
2394 if isPENDING:
2395 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2396 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002397 else:
GlennRCed771242016-01-13 17:02:47 -08002398 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2399 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002400 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002401 except ( TypeError, ValueError ):
2402 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002403 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002404
YPZhang240842b2016-05-17 12:00:50 -07002405 except AssertionError:
2406 main.log.exception( "" )
2407 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002408 except pexpect.EOF:
2409 main.log.error( self.name + ": EOF exception found" )
2410 main.log.error( self.name + ": " + self.handle.before )
2411 main.cleanup()
2412 main.exit()
2413 except Exception:
2414 main.log.exception( self.name + ": Uncaught exception!" )
2415 main.cleanup()
2416 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002417 except pexpect.TIMEOUT:
2418 main.log.error( self.name + ": ONOS timeout" )
2419 return None
2420
kelvin-onlab4df89f22015-04-13 18:10:23 -07002421
GlennRCed771242016-01-13 17:02:47 -08002422 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002423 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002424 """
andrewonlab87852b02014-11-19 18:44:19 -05002425 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002426 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002427 a specific point-to-point intent definition
2428 Required:
GlennRCed771242016-01-13 17:02:47 -08002429 * ingress: specify source dpid
2430 * egress: specify destination dpid
2431 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002432 Optional:
GlennRCed771242016-01-13 17:02:47 -08002433 * offset: the keyOffset is where the next batch of intents
2434 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002435 * noExit: If set to True, TestON will not exit if any error when issus command
2436 * getResponse: If set to True, function will return ONOS response.
2437
GlennRCed771242016-01-13 17:02:47 -08002438 Returns: If failed to push test intents, it will returen None,
2439 if successful, return true.
2440 Timeout expection will return None,
2441 TypeError will return false
2442 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002443 """
andrewonlab87852b02014-11-19 18:44:19 -05002444 try:
GlennRCed771242016-01-13 17:02:47 -08002445 if background:
2446 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002447 else:
GlennRCed771242016-01-13 17:02:47 -08002448 back = ""
2449 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002450 ingress,
2451 egress,
2452 batchSize,
2453 offset,
2454 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002455 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002456 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002457 main.log.info( response )
2458 if response == None:
2459 return None
2460
YPZhangb34b7e12016-06-14 14:28:19 -07002461 if getResponse:
2462 return response
2463
GlennRCed771242016-01-13 17:02:47 -08002464 # TODO: We should handle if there is failure in installation
2465 return main.TRUE
2466
Jon Hallc6793552016-01-19 14:18:37 -08002467 except AssertionError:
2468 main.log.exception( "" )
2469 return None
GlennRCed771242016-01-13 17:02:47 -08002470 except pexpect.TIMEOUT:
2471 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002472 return None
andrewonlab87852b02014-11-19 18:44:19 -05002473 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002474 main.log.error( self.name + ": EOF exception found" )
2475 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002476 main.cleanup()
2477 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002478 except TypeError:
2479 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002480 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002481 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002482 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002483 main.cleanup()
2484 main.exit()
2485
YPZhangebf9eb52016-05-12 15:20:24 -07002486 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002487 """
2488 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002489 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002490 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002491 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002492 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002493 """
YPZhange3109a72016-02-02 11:25:37 -08002494
YPZhangb5d3f832016-01-23 22:54:26 -08002495 try:
YPZhange3109a72016-02-02 11:25:37 -08002496 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002497 cmd = "flows -c added"
2498 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2499 if rawFlows:
2500 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002501 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002502 for l in rawFlows:
2503 totalFlows += int(l.split("Count=")[1])
2504 else:
2505 main.log.error("Response not as expected!")
2506 return None
2507 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002508
You Wangd3cb2ce2016-05-16 14:01:24 -07002509 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002510 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002511 return None
2512 except pexpect.EOF:
2513 main.log.error( self.name + ": EOF exception found" )
2514 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002515 if not noExit:
2516 main.cleanup()
2517 main.exit()
2518 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002519 except Exception:
2520 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002521 if not noExit:
2522 main.cleanup()
2523 main.exit()
2524 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002525 except pexpect.TIMEOUT:
2526 main.log.error( self.name + ": ONOS timeout" )
2527 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002528
YPZhang14a4aa92016-07-15 13:37:15 -07002529 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002530 """
2531 Description:
2532 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002533 Optional:
2534 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002535 Return:
2536 The number of intents
2537 """
2538 try:
2539 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002540 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002541 if response == None:
2542 return -1
2543 response = json.loads( response )
2544 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002545 except ( TypeError, ValueError ):
2546 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002547 return None
2548 except pexpect.EOF:
2549 main.log.error( self.name + ": EOF exception found" )
2550 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002551 if noExit:
2552 return -1
2553 else:
2554 main.cleanup()
2555 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002556 except Exception:
2557 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002558 if noExit:
2559 return -1
2560 else:
2561 main.cleanup()
2562 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002563
kelvin-onlabd3b64892015-01-20 13:26:24 -08002564 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002565 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002566 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002567 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002569 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002570 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002571 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002573 cmdStr += " -j"
2574 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002575 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002576 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002577 except AssertionError:
2578 main.log.exception( "" )
2579 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002580 except TypeError:
2581 main.log.exception( self.name + ": Object not as expected" )
2582 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002584 main.log.error( self.name + ": EOF exception found" )
2585 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002586 main.cleanup()
2587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002588 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002589 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002590 main.cleanup()
2591 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002592
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002594 """
2595 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002596 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002598 """
andrewonlab867212a2014-10-22 20:13:38 -04002599 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002600 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002602 cmdStr += " -j"
2603 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002604 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002605 if handle:
2606 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002607 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002608 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002609 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002610 else:
2611 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002612 except AssertionError:
2613 main.log.exception( "" )
2614 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002615 except TypeError:
2616 main.log.exception( self.name + ": Object not as expected" )
2617 return None
andrewonlab867212a2014-10-22 20:13:38 -04002618 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002619 main.log.error( self.name + ": EOF exception found" )
2620 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002621 main.cleanup()
2622 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002623 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002624 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002625 main.cleanup()
2626 main.exit()
2627
kelvin8ec71442015-01-15 16:57:00 -08002628 # Wrapper functions ****************
2629 # Wrapper functions use existing driver
2630 # functions and extends their use case.
2631 # For example, we may use the output of
2632 # a normal driver function, and parse it
2633 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002634
kelvin-onlabd3b64892015-01-20 13:26:24 -08002635 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002636 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002637 Description:
2638 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002639 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002640 try:
kelvin8ec71442015-01-15 16:57:00 -08002641 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002642 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002643 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002644
kelvin8ec71442015-01-15 16:57:00 -08002645 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2647 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002648 match = re.search('id=0x([\da-f]+),', intents)
2649 if match:
2650 tmpId = match.group()[3:-1]
2651 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002652 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002653
Jon Halld4d4b372015-01-28 16:02:41 -08002654 except TypeError:
2655 main.log.exception( self.name + ": Object not as expected" )
2656 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002657 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002658 main.log.error( self.name + ": EOF exception found" )
2659 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002660 main.cleanup()
2661 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002662 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002663 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002664 main.cleanup()
2665 main.exit()
2666
You Wang3c276252016-09-21 15:21:36 -07002667 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002668 """
2669 Determine the number of flow rules for the given device id that are
2670 in the added state
You Wang3c276252016-09-21 15:21:36 -07002671 Params:
2672 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002673 """
2674 try:
You Wang3c276252016-09-21 15:21:36 -07002675 if core:
2676 cmdStr = "flows any " + str( deviceId ) + " | " +\
2677 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2678 else:
2679 cmdStr = "flows any " + str( deviceId ) + " | " +\
2680 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002681 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002682 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002683 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002684 except AssertionError:
2685 main.log.exception( "" )
2686 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002687 except pexpect.EOF:
2688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
2690 main.cleanup()
2691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002692 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002693 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002694 main.cleanup()
2695 main.exit()
2696
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002699 Use 'devices' function to obtain list of all devices
2700 and parse the result to obtain a list of all device
2701 id's. Returns this list. Returns empty list if no
2702 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002703 List is ordered sequentially
2704
andrewonlab3e15ead2014-10-15 14:21:34 -04002705 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002706 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002707 the ids. By obtaining the list of device ids on the fly,
2708 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002709 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002710 try:
kelvin8ec71442015-01-15 16:57:00 -08002711 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 devicesStr = self.devices( jsonFormat=False )
2713 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002714
kelvin-onlabd3b64892015-01-20 13:26:24 -08002715 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002716 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002717 return idList
kelvin8ec71442015-01-15 16:57:00 -08002718
2719 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002721 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002723 # Split list further into arguments before and after string
2724 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 # append to idList
2726 for arg in tempList:
2727 idList.append( arg.split( "id=" )[ 1 ] )
2728 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002729
Jon Halld4d4b372015-01-28 16:02:41 -08002730 except TypeError:
2731 main.log.exception( self.name + ": Object not as expected" )
2732 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002733 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002734 main.log.error( self.name + ": EOF exception found" )
2735 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002736 main.cleanup()
2737 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002738 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002739 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002740 main.cleanup()
2741 main.exit()
2742
kelvin-onlabd3b64892015-01-20 13:26:24 -08002743 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002744 """
andrewonlab7c211572014-10-15 16:45:20 -04002745 Uses 'nodes' function to obtain list of all nodes
2746 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002747 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002748 Returns:
2749 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002750 """
andrewonlab7c211572014-10-15 16:45:20 -04002751 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002752 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002753 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002754 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002755 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002756 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002757 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002758 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002759 nodesJson = json.loads( nodesStr )
2760 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002761 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002762 except ( TypeError, ValueError ):
2763 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002764 return None
andrewonlab7c211572014-10-15 16:45:20 -04002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002768 main.cleanup()
2769 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002772 main.cleanup()
2773 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002774
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002776 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002777 Return the first device from the devices api whose 'id' contains 'dpid'
2778 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002779 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002780 try:
kelvin8ec71442015-01-15 16:57:00 -08002781 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002782 return None
2783 else:
kelvin8ec71442015-01-15 16:57:00 -08002784 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 rawDevices = self.devices()
2786 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002787 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002788 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002789 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2790 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002791 return device
2792 return None
Jon Hallc6793552016-01-19 14:18:37 -08002793 except ( TypeError, ValueError ):
2794 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002795 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002796 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002797 main.log.error( self.name + ": EOF exception found" )
2798 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002799 main.cleanup()
2800 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002801 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002802 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002803 main.cleanup()
2804 main.exit()
2805
You Wang24139872016-05-03 11:48:47 -07002806 def getTopology( self, topologyOutput ):
2807 """
2808 Definition:
2809 Loads a json topology output
2810 Return:
2811 topology = current ONOS topology
2812 """
2813 import json
2814 try:
2815 # either onos:topology or 'topology' will work in CLI
2816 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002817 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002818 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002819 except ( TypeError, ValueError ):
2820 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2821 return None
You Wang24139872016-05-03 11:48:47 -07002822 except pexpect.EOF:
2823 main.log.error( self.name + ": EOF exception found" )
2824 main.log.error( self.name + ": " + self.handle.before )
2825 main.cleanup()
2826 main.exit()
2827 except Exception:
2828 main.log.exception( self.name + ": Uncaught exception!" )
2829 main.cleanup()
2830 main.exit()
2831
Flavio Castro82ee2f62016-06-07 15:04:12 -07002832 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002833 """
Jon Hallefbd9792015-03-05 16:11:36 -08002834 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002835 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002836 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002837
Flavio Castro82ee2f62016-06-07 15:04:12 -07002838 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002839 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002840 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002841 logLevel = level to log to.
2842 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002843
Jon Hallefbd9792015-03-05 16:11:36 -08002844 Returns: main.TRUE if the number of switches and links are correct,
2845 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002846 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002847 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002848 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002849 try:
You Wang13310252016-07-31 10:56:14 -07002850 summary = self.summary()
2851 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002852 except ( TypeError, ValueError ):
2853 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2854 return main.ERROR
2855 try:
2856 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002857 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002858 return main.ERROR
2859 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002860 # Is the number of switches is what we expected
2861 devices = topology.get( 'devices', False )
2862 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002863 nodes = summary.get( 'nodes', False )
2864 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002865 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002866 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002867 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002868 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002869 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2870 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002871 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002872 output = output + "The number of links and switches match "\
2873 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002874 result = main.TRUE
2875 else:
You Wang24139872016-05-03 11:48:47 -07002876 output = output + \
2877 "The number of links and switches does not match " + \
2878 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002879 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002880 output = output + "\n ONOS sees %i devices" % int( devices )
2881 output = output + " (%i expected) " % int( numoswitch )
2882 output = output + "and %i links " % int( links )
2883 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002884 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002885 output = output + "and %i controllers " % int( nodes )
2886 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002887 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002888 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002889 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002890 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002891 else:
You Wang24139872016-05-03 11:48:47 -07002892 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002893 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002895 main.log.error( self.name + ": EOF exception found" )
2896 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002897 main.cleanup()
2898 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002899 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002900 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002901 main.cleanup()
2902 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002903
kelvin-onlabd3b64892015-01-20 13:26:24 -08002904 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002905 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002906 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 deviceId must be the id of a device as seen in the onos devices command
2908 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002909 role must be either master, standby, or none
2910
Jon Halle3f39ff2015-01-13 11:50:53 -08002911 Returns:
2912 main.TRUE or main.FALSE based on argument verification and
2913 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002914 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002915 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002916 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002917 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002918 cmdStr = "device-role " +\
2919 str( deviceId ) + " " +\
2920 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002921 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002923 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002924 if re.search( "Error", handle ):
2925 # end color output to escape any colours
2926 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002927 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002929 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002930 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002931 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002932 main.log.error( "Invalid 'role' given to device_role(). " +
2933 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002934 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002935 except AssertionError:
2936 main.log.exception( "" )
2937 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002938 except TypeError:
2939 main.log.exception( self.name + ": Object not as expected" )
2940 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002942 main.log.error( self.name + ": EOF exception found" )
2943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002944 main.cleanup()
2945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002947 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002948 main.cleanup()
2949 main.exit()
2950
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002952 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002953 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002954 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002956 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002957 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002958 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002959 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002960 cmdStr += " -j"
2961 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002962 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002963 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002964 except AssertionError:
2965 main.log.exception( "" )
2966 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002967 except TypeError:
2968 main.log.exception( self.name + ": Object not as expected" )
2969 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002970 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002971 main.log.error( self.name + ": EOF exception found" )
2972 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002973 main.cleanup()
2974 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002975 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002976 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002977 main.cleanup()
2978 main.exit()
2979
kelvin-onlabd3b64892015-01-20 13:26:24 -08002980 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002981 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002982 CLI command to get the current leader for the Election test application
2983 NOTE: Requires installation of the onos-app-election feature
2984 Returns: Node IP of the leader if one exists
2985 None if none exists
2986 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002987 """
Jon Hall94fd0472014-12-08 11:52:42 -08002988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002989 cmdStr = "election-test-leader"
2990 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002991 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 # Leader
2993 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002995 nodeSearch = re.search( leaderPattern, response )
2996 if nodeSearch:
2997 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002998 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002999 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003000 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003001 # no leader
3002 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 nullSearch = re.search( nullPattern, response )
3005 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003006 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003007 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003008 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003010 main.log.error( "Error in electionTestLeader on " + self.name +
3011 ": " + "unexpected response" )
3012 main.log.error( repr( response ) )
3013 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003014 except AssertionError:
3015 main.log.exception( "" )
3016 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003017 except TypeError:
3018 main.log.exception( self.name + ": Object not as expected" )
3019 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003021 main.log.error( self.name + ": EOF exception found" )
3022 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003023 main.cleanup()
3024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003026 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003027 main.cleanup()
3028 main.exit()
3029
kelvin-onlabd3b64892015-01-20 13:26:24 -08003030 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003031 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003032 CLI command to run for leadership of the Election test application.
3033 NOTE: Requires installation of the onos-app-election feature
3034 Returns: Main.TRUE on success
3035 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003036 """
Jon Hall94fd0472014-12-08 11:52:42 -08003037 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003038 cmdStr = "election-test-run"
3039 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003040 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003041 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003042 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003044 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003045 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003046 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003048 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003049 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003050 main.log.error( "Error in electionTestRun on " + self.name +
3051 ": " + "unexpected response" )
3052 main.log.error( repr( response ) )
3053 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003054 except AssertionError:
3055 main.log.exception( "" )
3056 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003057 except TypeError:
3058 main.log.exception( self.name + ": Object not as expected" )
3059 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003060 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003063 main.cleanup()
3064 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003065 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003066 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003067 main.cleanup()
3068 main.exit()
3069
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Jon Hall94fd0472014-12-08 11:52:42 -08003072 * CLI command to withdraw the local node from leadership election for
3073 * the Election test application.
3074 #NOTE: Requires installation of the onos-app-election feature
3075 Returns: Main.TRUE on success
3076 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003077 """
Jon Hall94fd0472014-12-08 11:52:42 -08003078 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003079 cmdStr = "election-test-withdraw"
3080 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003081 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003082 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003083 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003084 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003085 if re.search( successPattern, response ):
3086 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003087 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003088 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003089 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003090 main.log.error( "Error in electionTestWithdraw on " +
3091 self.name + ": " + "unexpected response" )
3092 main.log.error( repr( response ) )
3093 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003094 except AssertionError:
3095 main.log.exception( "" )
3096 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003097 except TypeError:
3098 main.log.exception( self.name + ": Object not as expected" )
3099 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003101 main.log.error( self.name + ": EOF exception found" )
3102 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003103 main.cleanup()
3104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003106 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003107 main.cleanup()
3108 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003109
kelvin8ec71442015-01-15 16:57:00 -08003110 def getDevicePortsEnabledCount( self, dpid ):
3111 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003112 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003113 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003114 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003116 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3117 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003118 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003119 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003120 if re.search( "No such device", output ):
3121 main.log.error( "Error in getting ports" )
3122 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003123 return output
Jon Hallc6793552016-01-19 14:18:37 -08003124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003133 main.cleanup()
3134 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003136 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 main.cleanup()
3138 main.exit()
3139
kelvin8ec71442015-01-15 16:57:00 -08003140 def getDeviceLinksActiveCount( self, dpid ):
3141 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003142 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003143 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003144 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003145 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3147 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003149 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003150 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003151 main.log.error( "Error in getting ports " )
3152 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003153 return output
Jon Hallc6793552016-01-19 14:18:37 -08003154 except AssertionError:
3155 main.log.exception( "" )
3156 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003163 main.cleanup()
3164 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003165 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003166 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167 main.cleanup()
3168 main.exit()
3169
kelvin8ec71442015-01-15 16:57:00 -08003170 def getAllIntentIds( self ):
3171 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003172 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003173 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003174 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 cmdStr = "onos:intents | grep id="
3176 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003177 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003178 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003179 if re.search( "Error", output ):
3180 main.log.error( "Error in getting ports" )
3181 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003182 return output
Jon Hallc6793552016-01-19 14:18:37 -08003183 except AssertionError:
3184 main.log.exception( "" )
3185 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003186 except TypeError:
3187 main.log.exception( self.name + ": Object not as expected" )
3188 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003189 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003190 main.log.error( self.name + ": EOF exception found" )
3191 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003192 main.cleanup()
3193 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003194 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003195 main.log.exception( self.name + ": Uncaught exception!" )
3196 main.cleanup()
3197 main.exit()
3198
Jon Hall73509952015-02-24 16:42:56 -08003199 def intentSummary( self ):
3200 """
Jon Hallefbd9792015-03-05 16:11:36 -08003201 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003202 """
3203 try:
3204 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003205 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003206 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003207 states.append( intent.get( 'state', None ) )
3208 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003209 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003210 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003211 except ( TypeError, ValueError ):
3212 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003213 return None
3214 except pexpect.EOF:
3215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
3217 main.cleanup()
3218 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003219 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003220 main.log.exception( self.name + ": Uncaught exception!" )
3221 main.cleanup()
3222 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003223
Jon Hall61282e32015-03-19 11:34:11 -07003224 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003225 """
3226 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003227 Optional argument:
3228 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003229 """
Jon Hall63604932015-02-26 17:09:50 -08003230 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003231 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003232 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003233 cmdStr += " -j"
3234 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003235 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003236 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003237 return output
Jon Hallc6793552016-01-19 14:18:37 -08003238 except AssertionError:
3239 main.log.exception( "" )
3240 return None
Jon Hall63604932015-02-26 17:09:50 -08003241 except TypeError:
3242 main.log.exception( self.name + ": Object not as expected" )
3243 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003244 except pexpect.EOF:
3245 main.log.error( self.name + ": EOF exception found" )
3246 main.log.error( self.name + ": " + self.handle.before )
3247 main.cleanup()
3248 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003249 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003250 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003251 main.cleanup()
3252 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003253
acsmarsa4a4d1e2015-07-10 16:01:24 -07003254 def leaderCandidates( self, jsonFormat=True ):
3255 """
3256 Returns the output of the leaders -c command.
3257 Optional argument:
3258 * jsonFormat - boolean indicating if you want output in json
3259 """
3260 try:
3261 cmdStr = "onos:leaders -c"
3262 if jsonFormat:
3263 cmdStr += " -j"
3264 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003265 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003266 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003267 return output
Jon Hallc6793552016-01-19 14:18:37 -08003268 except AssertionError:
3269 main.log.exception( "" )
3270 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003271 except TypeError:
3272 main.log.exception( self.name + ": Object not as expected" )
3273 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 Hallc6793552016-01-19 14:18:37 -08003284 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003285 """
3286 Returns a list in format [leader,candidate1,candidate2,...] for a given
3287 topic parameter and an empty list if the topic doesn't exist
3288 If no leader is elected leader in the returned list will be "none"
3289 Returns None if there is a type error processing the json object
3290 """
3291 try:
Jon Hall6e709752016-02-01 13:38:46 -08003292 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003293 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003294 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003295 assert "Command not found:" not in rawOutput, rawOutput
3296 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003297 results = []
3298 for dict in output:
3299 if dict["topic"] == topic:
3300 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003301 candidates = re.split( ", ", dict["candidates"][1:-1] )
3302 results.append( leader )
3303 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003304 return results
Jon Hallc6793552016-01-19 14:18:37 -08003305 except AssertionError:
3306 main.log.exception( "" )
3307 return None
3308 except ( TypeError, ValueError ):
3309 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003310 return None
3311 except pexpect.EOF:
3312 main.log.error( self.name + ": EOF exception found" )
3313 main.log.error( self.name + ": " + self.handle.before )
3314 main.cleanup()
3315 main.exit()
3316 except Exception:
3317 main.log.exception( self.name + ": Uncaught exception!" )
3318 main.cleanup()
3319 main.exit()
3320
Jon Hall61282e32015-03-19 11:34:11 -07003321 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003322 """
3323 Returns the output of the intent Pending map.
3324 """
Jon Hall63604932015-02-26 17:09:50 -08003325 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003326 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003327 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003328 cmdStr += " -j"
3329 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003330 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003331 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 return output
Jon Hallc6793552016-01-19 14:18:37 -08003333 except AssertionError:
3334 main.log.exception( "" )
3335 return None
Jon Hall63604932015-02-26 17:09:50 -08003336 except TypeError:
3337 main.log.exception( self.name + ": Object not as expected" )
3338 return None
3339 except pexpect.EOF:
3340 main.log.error( self.name + ": EOF exception found" )
3341 main.log.error( self.name + ": " + self.handle.before )
3342 main.cleanup()
3343 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003344 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003345 main.log.exception( self.name + ": Uncaught exception!" )
3346 main.cleanup()
3347 main.exit()
3348
Jon Hall61282e32015-03-19 11:34:11 -07003349 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003350 """
3351 Returns the output of the raft partitions command for ONOS.
3352 """
Jon Hall61282e32015-03-19 11:34:11 -07003353 # Sample JSON
3354 # {
3355 # "leader": "tcp://10.128.30.11:7238",
3356 # "members": [
3357 # "tcp://10.128.30.11:7238",
3358 # "tcp://10.128.30.17:7238",
3359 # "tcp://10.128.30.13:7238",
3360 # ],
3361 # "name": "p1",
3362 # "term": 3
3363 # },
Jon Hall63604932015-02-26 17:09:50 -08003364 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003365 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003366 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003367 cmdStr += " -j"
3368 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003369 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003370 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003371 return output
Jon Hallc6793552016-01-19 14:18:37 -08003372 except AssertionError:
3373 main.log.exception( "" )
3374 return None
Jon Hall63604932015-02-26 17:09:50 -08003375 except TypeError:
3376 main.log.exception( self.name + ": Object not as expected" )
3377 return None
3378 except pexpect.EOF:
3379 main.log.error( self.name + ": EOF exception found" )
3380 main.log.error( self.name + ": " + self.handle.before )
3381 main.cleanup()
3382 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003383 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003384 main.log.exception( self.name + ": Uncaught exception!" )
3385 main.cleanup()
3386 main.exit()
3387
Jon Halle9f909e2016-09-23 10:43:12 -07003388 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003389 """
3390 Returns the output of the apps command for ONOS. This command lists
3391 information about installed ONOS applications
3392 """
3393 # Sample JSON object
3394 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3395 # "description":"ONOS OpenFlow protocol southbound providers",
3396 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3397 # "features":"[onos-openflow]","state":"ACTIVE"}]
3398 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003399 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003400 if summary:
3401 cmdStr += " -s"
3402 if active:
3403 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003404 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003405 cmdStr += " -j"
3406 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003407 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003408 assert "Command not found:" not in output, output
3409 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003410 return output
Jon Hallbe379602015-03-24 13:39:32 -07003411 # FIXME: look at specific exceptions/Errors
3412 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003413 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003414 return None
3415 except TypeError:
3416 main.log.exception( self.name + ": Object not as expected" )
3417 return None
3418 except pexpect.EOF:
3419 main.log.error( self.name + ": EOF exception found" )
3420 main.log.error( self.name + ": " + self.handle.before )
3421 main.cleanup()
3422 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003423 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003424 main.log.exception( self.name + ": Uncaught exception!" )
3425 main.cleanup()
3426 main.exit()
3427
Jon Hall146f1522015-03-24 15:33:24 -07003428 def appStatus( self, appName ):
3429 """
3430 Uses the onos:apps cli command to return the status of an application.
3431 Returns:
3432 "ACTIVE" - If app is installed and activated
3433 "INSTALLED" - If app is installed and deactivated
3434 "UNINSTALLED" - If app is not installed
3435 None - on error
3436 """
Jon Hall146f1522015-03-24 15:33:24 -07003437 try:
3438 if not isinstance( appName, types.StringType ):
3439 main.log.error( self.name + ".appStatus(): appName must be" +
3440 " a string" )
3441 return None
3442 output = self.apps( jsonFormat=True )
3443 appsJson = json.loads( output )
3444 state = None
3445 for app in appsJson:
3446 if appName == app.get('name'):
3447 state = app.get('state')
3448 break
3449 if state == "ACTIVE" or state == "INSTALLED":
3450 return state
3451 elif state is None:
3452 return "UNINSTALLED"
3453 elif state:
3454 main.log.error( "Unexpected state from 'onos:apps': " +
3455 str( state ) )
3456 return state
Jon Hallc6793552016-01-19 14:18:37 -08003457 except ( TypeError, ValueError ):
3458 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003459 return None
3460 except pexpect.EOF:
3461 main.log.error( self.name + ": EOF exception found" )
3462 main.log.error( self.name + ": " + self.handle.before )
3463 main.cleanup()
3464 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003465 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003466 main.log.exception( self.name + ": Uncaught exception!" )
3467 main.cleanup()
3468 main.exit()
3469
Jon Hallbe379602015-03-24 13:39:32 -07003470 def app( self, appName, option ):
3471 """
3472 Interacts with the app command for ONOS. This command manages
3473 application inventory.
3474 """
Jon Hallbe379602015-03-24 13:39:32 -07003475 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003476 # Validate argument types
3477 valid = True
3478 if not isinstance( appName, types.StringType ):
3479 main.log.error( self.name + ".app(): appName must be a " +
3480 "string" )
3481 valid = False
3482 if not isinstance( option, types.StringType ):
3483 main.log.error( self.name + ".app(): option must be a string" )
3484 valid = False
3485 if not valid:
3486 return main.FALSE
3487 # Validate Option
3488 option = option.lower()
3489 # NOTE: Install may become a valid option
3490 if option == "activate":
3491 pass
3492 elif option == "deactivate":
3493 pass
3494 elif option == "uninstall":
3495 pass
3496 else:
3497 # Invalid option
3498 main.log.error( "The ONOS app command argument only takes " +
3499 "the values: (activate|deactivate|uninstall)" +
3500 "; was given '" + option + "'")
3501 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003502 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003503 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003504 if "Error executing command" in output:
3505 main.log.error( "Error in processing onos:app command: " +
3506 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003507 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003508 elif "No such application" in output:
3509 main.log.error( "The application '" + appName +
3510 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003511 return main.FALSE
3512 elif "Command not found:" in output:
3513 main.log.error( "Error in processing onos:app command: " +
3514 str( output ) )
3515 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003516 elif "Unsupported command:" in output:
3517 main.log.error( "Incorrect command given to 'app': " +
3518 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003519 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003520 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003521 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003522 return main.TRUE
3523 except TypeError:
3524 main.log.exception( self.name + ": Object not as expected" )
3525 return main.ERROR
3526 except pexpect.EOF:
3527 main.log.error( self.name + ": EOF exception found" )
3528 main.log.error( self.name + ": " + self.handle.before )
3529 main.cleanup()
3530 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003531 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003532 main.log.exception( self.name + ": Uncaught exception!" )
3533 main.cleanup()
3534 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003535
Jon Hallbd16b922015-03-26 17:53:15 -07003536 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003537 """
3538 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003539 appName is the hierarchical app name, not the feature name
3540 If check is True, method will check the status of the app after the
3541 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003542 Returns main.TRUE if the command was successfully sent
3543 main.FALSE if the cli responded with an error or given
3544 incorrect input
3545 """
3546 try:
3547 if not isinstance( appName, types.StringType ):
3548 main.log.error( self.name + ".activateApp(): appName must be" +
3549 " a string" )
3550 return main.FALSE
3551 status = self.appStatus( appName )
3552 if status == "INSTALLED":
3553 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003554 if check and response == main.TRUE:
3555 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003556 status = self.appStatus( appName )
3557 if status == "ACTIVE":
3558 return main.TRUE
3559 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003560 main.log.debug( "The state of application " +
3561 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003562 time.sleep( 1 )
3563 return main.FALSE
3564 else: # not 'check' or command didn't succeed
3565 return response
Jon Hall146f1522015-03-24 15:33:24 -07003566 elif status == "ACTIVE":
3567 return main.TRUE
3568 elif status == "UNINSTALLED":
3569 main.log.error( self.name + ": Tried to activate the " +
3570 "application '" + appName + "' which is not " +
3571 "installed." )
3572 else:
3573 main.log.error( "Unexpected return value from appStatus: " +
3574 str( status ) )
3575 return main.ERROR
3576 except TypeError:
3577 main.log.exception( self.name + ": Object not as expected" )
3578 return main.ERROR
3579 except pexpect.EOF:
3580 main.log.error( self.name + ": EOF exception found" )
3581 main.log.error( self.name + ": " + self.handle.before )
3582 main.cleanup()
3583 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003584 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003585 main.log.exception( self.name + ": Uncaught exception!" )
3586 main.cleanup()
3587 main.exit()
3588
Jon Hallbd16b922015-03-26 17:53:15 -07003589 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003590 """
3591 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003592 appName is the hierarchical app name, not the feature name
3593 If check is True, method will check the status of the app after the
3594 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003595 Returns main.TRUE if the command was successfully sent
3596 main.FALSE if the cli responded with an error or given
3597 incorrect input
3598 """
3599 try:
3600 if not isinstance( appName, types.StringType ):
3601 main.log.error( self.name + ".deactivateApp(): appName must " +
3602 "be a string" )
3603 return main.FALSE
3604 status = self.appStatus( appName )
3605 if status == "INSTALLED":
3606 return main.TRUE
3607 elif status == "ACTIVE":
3608 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003609 if check and response == main.TRUE:
3610 for i in range(10): # try 10 times then give up
3611 status = self.appStatus( appName )
3612 if status == "INSTALLED":
3613 return main.TRUE
3614 else:
3615 time.sleep( 1 )
3616 return main.FALSE
3617 else: # not check or command didn't succeed
3618 return response
Jon Hall146f1522015-03-24 15:33:24 -07003619 elif status == "UNINSTALLED":
3620 main.log.warn( self.name + ": Tried to deactivate the " +
3621 "application '" + appName + "' which is not " +
3622 "installed." )
3623 return main.TRUE
3624 else:
3625 main.log.error( "Unexpected return value from appStatus: " +
3626 str( status ) )
3627 return main.ERROR
3628 except TypeError:
3629 main.log.exception( self.name + ": Object not as expected" )
3630 return main.ERROR
3631 except pexpect.EOF:
3632 main.log.error( self.name + ": EOF exception found" )
3633 main.log.error( self.name + ": " + self.handle.before )
3634 main.cleanup()
3635 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003636 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003637 main.log.exception( self.name + ": Uncaught exception!" )
3638 main.cleanup()
3639 main.exit()
3640
Jon Hallbd16b922015-03-26 17:53:15 -07003641 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003642 """
3643 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003644 appName is the hierarchical app name, not the feature name
3645 If check is True, method will check the status of the app after the
3646 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003647 Returns main.TRUE if the command was successfully sent
3648 main.FALSE if the cli responded with an error or given
3649 incorrect input
3650 """
3651 # TODO: check with Thomas about the state machine for apps
3652 try:
3653 if not isinstance( appName, types.StringType ):
3654 main.log.error( self.name + ".uninstallApp(): appName must " +
3655 "be a string" )
3656 return main.FALSE
3657 status = self.appStatus( appName )
3658 if status == "INSTALLED":
3659 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003660 if check and response == main.TRUE:
3661 for i in range(10): # try 10 times then give up
3662 status = self.appStatus( appName )
3663 if status == "UNINSTALLED":
3664 return main.TRUE
3665 else:
3666 time.sleep( 1 )
3667 return main.FALSE
3668 else: # not check or command didn't succeed
3669 return response
Jon Hall146f1522015-03-24 15:33:24 -07003670 elif status == "ACTIVE":
3671 main.log.warn( self.name + ": Tried to uninstall the " +
3672 "application '" + appName + "' which is " +
3673 "currently active." )
3674 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003675 if check and response == main.TRUE:
3676 for i in range(10): # try 10 times then give up
3677 status = self.appStatus( appName )
3678 if status == "UNINSTALLED":
3679 return main.TRUE
3680 else:
3681 time.sleep( 1 )
3682 return main.FALSE
3683 else: # not check or command didn't succeed
3684 return response
Jon Hall146f1522015-03-24 15:33:24 -07003685 elif status == "UNINSTALLED":
3686 return main.TRUE
3687 else:
3688 main.log.error( "Unexpected return value from appStatus: " +
3689 str( status ) )
3690 return main.ERROR
3691 except TypeError:
3692 main.log.exception( self.name + ": Object not as expected" )
3693 return main.ERROR
3694 except pexpect.EOF:
3695 main.log.error( self.name + ": EOF exception found" )
3696 main.log.error( self.name + ": " + self.handle.before )
3697 main.cleanup()
3698 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003699 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003700 main.log.exception( self.name + ": Uncaught exception!" )
3701 main.cleanup()
3702 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003703
3704 def appIDs( self, jsonFormat=True ):
3705 """
3706 Show the mappings between app id and app names given by the 'app-ids'
3707 cli command
3708 """
3709 try:
3710 cmdStr = "app-ids"
3711 if jsonFormat:
3712 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003713 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003714 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
3716 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003717 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003718 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003719 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003720 return None
3721 except TypeError:
3722 main.log.exception( self.name + ": Object not as expected" )
3723 return None
3724 except pexpect.EOF:
3725 main.log.error( self.name + ": EOF exception found" )
3726 main.log.error( self.name + ": " + self.handle.before )
3727 main.cleanup()
3728 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003729 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003730 main.log.exception( self.name + ": Uncaught exception!" )
3731 main.cleanup()
3732 main.exit()
3733
3734 def appToIDCheck( self ):
3735 """
3736 This method will check that each application's ID listed in 'apps' is
3737 the same as the ID listed in 'app-ids'. The check will also check that
3738 there are no duplicate IDs issued. Note that an app ID should be
3739 a globaly unique numerical identifier for app/app-like features. Once
3740 an ID is registered, the ID is never freed up so that if an app is
3741 reinstalled it will have the same ID.
3742
3743 Returns: main.TRUE if the check passes and
3744 main.FALSE if the check fails or
3745 main.ERROR if there is some error in processing the test
3746 """
3747 try:
Jon Hall390696c2015-05-05 17:13:41 -07003748 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003749 rawJson = self.appIDs( jsonFormat=True )
3750 if rawJson:
3751 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003752 else:
Jon Hallc6793552016-01-19 14:18:37 -08003753 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003754 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003755 rawJson = self.apps( jsonFormat=True )
3756 if rawJson:
3757 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003758 else:
Jon Hallc6793552016-01-19 14:18:37 -08003759 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003760 bail = True
3761 if bail:
3762 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003763 result = main.TRUE
3764 for app in apps:
3765 appID = app.get( 'id' )
3766 if appID is None:
3767 main.log.error( "Error parsing app: " + str( app ) )
3768 result = main.FALSE
3769 appName = app.get( 'name' )
3770 if appName is None:
3771 main.log.error( "Error parsing app: " + str( app ) )
3772 result = main.FALSE
3773 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003774 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003775 # main.log.debug( "Comparing " + str( app ) + " to " +
3776 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003777 if not current: # if ids doesn't have this id
3778 result = main.FALSE
3779 main.log.error( "'app-ids' does not have the ID for " +
3780 str( appName ) + " that apps does." )
3781 elif len( current ) > 1:
3782 # there is more than one app with this ID
3783 result = main.FALSE
3784 # We will log this later in the method
3785 elif not current[0][ 'name' ] == appName:
3786 currentName = current[0][ 'name' ]
3787 result = main.FALSE
3788 main.log.error( "'app-ids' has " + str( currentName ) +
3789 " registered under id:" + str( appID ) +
3790 " but 'apps' has " + str( appName ) )
3791 else:
3792 pass # id and name match!
3793 # now make sure that app-ids has no duplicates
3794 idsList = []
3795 namesList = []
3796 for item in ids:
3797 idsList.append( item[ 'id' ] )
3798 namesList.append( item[ 'name' ] )
3799 if len( idsList ) != len( set( idsList ) ) or\
3800 len( namesList ) != len( set( namesList ) ):
3801 main.log.error( "'app-ids' has some duplicate entries: \n"
3802 + json.dumps( ids,
3803 sort_keys=True,
3804 indent=4,
3805 separators=( ',', ': ' ) ) )
3806 result = main.FALSE
3807 return result
Jon Hallc6793552016-01-19 14:18:37 -08003808 except ( TypeError, ValueError ):
3809 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003810 return main.ERROR
3811 except pexpect.EOF:
3812 main.log.error( self.name + ": EOF exception found" )
3813 main.log.error( self.name + ": " + self.handle.before )
3814 main.cleanup()
3815 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003816 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003817 main.log.exception( self.name + ": Uncaught exception!" )
3818 main.cleanup()
3819 main.exit()
3820
Jon Hallfb760a02015-04-13 15:35:03 -07003821 def getCfg( self, component=None, propName=None, short=False,
3822 jsonFormat=True ):
3823 """
3824 Get configuration settings from onos cli
3825 Optional arguments:
3826 component - Optionally only list configurations for a specific
3827 component. If None, all components with configurations
3828 are displayed. Case Sensitive string.
3829 propName - If component is specified, propName option will show
3830 only this specific configuration from that component.
3831 Case Sensitive string.
3832 jsonFormat - Returns output as json. Note that this will override
3833 the short option
3834 short - Short, less verbose, version of configurations.
3835 This is overridden by the json option
3836 returns:
3837 Output from cli as a string or None on error
3838 """
3839 try:
3840 baseStr = "cfg"
3841 cmdStr = " get"
3842 componentStr = ""
3843 if component:
3844 componentStr += " " + component
3845 if propName:
3846 componentStr += " " + propName
3847 if jsonFormat:
3848 baseStr += " -j"
3849 elif short:
3850 baseStr += " -s"
3851 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003852 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003853 assert "Command not found:" not in output, output
3854 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003855 return output
3856 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003857 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003858 return None
3859 except TypeError:
3860 main.log.exception( self.name + ": Object not as expected" )
3861 return None
3862 except pexpect.EOF:
3863 main.log.error( self.name + ": EOF exception found" )
3864 main.log.error( self.name + ": " + self.handle.before )
3865 main.cleanup()
3866 main.exit()
3867 except Exception:
3868 main.log.exception( self.name + ": Uncaught exception!" )
3869 main.cleanup()
3870 main.exit()
3871
3872 def setCfg( self, component, propName, value=None, check=True ):
3873 """
3874 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003875 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003876 component - The case sensitive name of the component whose
3877 property is to be set
3878 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003879 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003880 value - The value to set the property to. If None, will unset the
3881 property and revert it to it's default value(if applicable)
3882 check - Boolean, Check whether the option was successfully set this
3883 only applies when a value is given.
3884 returns:
3885 main.TRUE on success or main.FALSE on failure. If check is False,
3886 will return main.TRUE unless there is an error
3887 """
3888 try:
3889 baseStr = "cfg"
3890 cmdStr = " set " + str( component ) + " " + str( propName )
3891 if value is not None:
3892 cmdStr += " " + str( value )
3893 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003894 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003895 assert "Command not found:" not in output, output
3896 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003897 if value and check:
3898 results = self.getCfg( component=str( component ),
3899 propName=str( propName ),
3900 jsonFormat=True )
3901 # Check if current value is what we just set
3902 try:
3903 jsonOutput = json.loads( results )
3904 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003905 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003906 main.log.exception( "Error parsing cfg output" )
3907 main.log.error( "output:" + repr( results ) )
3908 return main.FALSE
3909 if current == str( value ):
3910 return main.TRUE
3911 return main.FALSE
3912 return main.TRUE
3913 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003914 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003915 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003916 except ( TypeError, ValueError ):
3917 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003918 return main.FALSE
3919 except pexpect.EOF:
3920 main.log.error( self.name + ": EOF exception found" )
3921 main.log.error( self.name + ": " + self.handle.before )
3922 main.cleanup()
3923 main.exit()
3924 except Exception:
3925 main.log.exception( self.name + ": Uncaught exception!" )
3926 main.cleanup()
3927 main.exit()
3928
Jon Hall390696c2015-05-05 17:13:41 -07003929 def setTestAdd( self, setName, values ):
3930 """
3931 CLI command to add elements to a distributed set.
3932 Arguments:
3933 setName - The name of the set to add to.
3934 values - The value(s) to add to the set, space seperated.
3935 Example usages:
3936 setTestAdd( "set1", "a b c" )
3937 setTestAdd( "set2", "1" )
3938 returns:
3939 main.TRUE on success OR
3940 main.FALSE if elements were already in the set OR
3941 main.ERROR on error
3942 """
3943 try:
3944 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3945 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003946 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003947 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003948 try:
3949 # TODO: Maybe make this less hardcoded
3950 # ConsistentMap Exceptions
3951 assert "org.onosproject.store.service" not in output
3952 # Node not leader
3953 assert "java.lang.IllegalStateException" not in output
3954 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003955 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003956 "command: " + str( output ) )
3957 retryTime = 30 # Conservative time, given by Madan
3958 main.log.info( "Waiting " + str( retryTime ) +
3959 "seconds before retrying." )
3960 time.sleep( retryTime ) # Due to change in mastership
3961 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003962 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003963 assert "Error executing command" not in output
3964 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3965 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3966 main.log.info( self.name + ": " + output )
3967 if re.search( positiveMatch, output):
3968 return main.TRUE
3969 elif re.search( negativeMatch, output):
3970 return main.FALSE
3971 else:
3972 main.log.error( self.name + ": setTestAdd did not" +
3973 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003974 main.log.debug( self.name + " actual: " + repr( output ) )
3975 return main.ERROR
3976 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003977 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003978 return main.ERROR
3979 except TypeError:
3980 main.log.exception( self.name + ": Object not as expected" )
3981 return main.ERROR
3982 except pexpect.EOF:
3983 main.log.error( self.name + ": EOF exception found" )
3984 main.log.error( self.name + ": " + self.handle.before )
3985 main.cleanup()
3986 main.exit()
3987 except Exception:
3988 main.log.exception( self.name + ": Uncaught exception!" )
3989 main.cleanup()
3990 main.exit()
3991
3992 def setTestRemove( self, setName, values, clear=False, retain=False ):
3993 """
3994 CLI command to remove elements from a distributed set.
3995 Required arguments:
3996 setName - The name of the set to remove from.
3997 values - The value(s) to remove from the set, space seperated.
3998 Optional arguments:
3999 clear - Clear all elements from the set
4000 retain - Retain only the given values. (intersection of the
4001 original set and the given set)
4002 returns:
4003 main.TRUE on success OR
4004 main.FALSE if the set was not changed OR
4005 main.ERROR on error
4006 """
4007 try:
4008 cmdStr = "set-test-remove "
4009 if clear:
4010 cmdStr += "-c " + str( setName )
4011 elif retain:
4012 cmdStr += "-r " + str( setName ) + " " + str( values )
4013 else:
4014 cmdStr += str( setName ) + " " + str( values )
4015 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004016 try:
Jon Halla495f562016-05-16 18:03:26 -07004017 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004018 # TODO: Maybe make this less hardcoded
4019 # ConsistentMap Exceptions
4020 assert "org.onosproject.store.service" not in output
4021 # Node not leader
4022 assert "java.lang.IllegalStateException" not in output
4023 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004024 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004025 "command: " + str( output ) )
4026 retryTime = 30 # Conservative time, given by Madan
4027 main.log.info( "Waiting " + str( retryTime ) +
4028 "seconds before retrying." )
4029 time.sleep( retryTime ) # Due to change in mastership
4030 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004031 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004032 assert "Command not found:" not in output, output
4033 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004034 main.log.info( self.name + ": " + output )
4035 if clear:
4036 pattern = "Set " + str( setName ) + " cleared"
4037 if re.search( pattern, output ):
4038 return main.TRUE
4039 elif retain:
4040 positivePattern = str( setName ) + " was pruned to contain " +\
4041 "only elements of set \[(.*)\]"
4042 negativePattern = str( setName ) + " was not changed by " +\
4043 "retaining only elements of the set " +\
4044 "\[(.*)\]"
4045 if re.search( positivePattern, output ):
4046 return main.TRUE
4047 elif re.search( negativePattern, output ):
4048 return main.FALSE
4049 else:
4050 positivePattern = "\[(.*)\] was removed from the set " +\
4051 str( setName )
4052 if ( len( values.split() ) == 1 ):
4053 negativePattern = "\[(.*)\] was not in set " +\
4054 str( setName )
4055 else:
4056 negativePattern = "No element of \[(.*)\] was in set " +\
4057 str( setName )
4058 if re.search( positivePattern, output ):
4059 return main.TRUE
4060 elif re.search( negativePattern, output ):
4061 return main.FALSE
4062 main.log.error( self.name + ": setTestRemove did not" +
4063 " match expected output" )
4064 main.log.debug( self.name + " expected: " + pattern )
4065 main.log.debug( self.name + " actual: " + repr( output ) )
4066 return main.ERROR
4067 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004068 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004069 return main.ERROR
4070 except TypeError:
4071 main.log.exception( self.name + ": Object not as expected" )
4072 return main.ERROR
4073 except pexpect.EOF:
4074 main.log.error( self.name + ": EOF exception found" )
4075 main.log.error( self.name + ": " + self.handle.before )
4076 main.cleanup()
4077 main.exit()
4078 except Exception:
4079 main.log.exception( self.name + ": Uncaught exception!" )
4080 main.cleanup()
4081 main.exit()
4082
4083 def setTestGet( self, setName, values="" ):
4084 """
4085 CLI command to get the elements in a distributed set.
4086 Required arguments:
4087 setName - The name of the set to remove from.
4088 Optional arguments:
4089 values - The value(s) to check if in the set, space seperated.
4090 returns:
4091 main.ERROR on error OR
4092 A list of elements in the set if no optional arguments are
4093 supplied OR
4094 A tuple containing the list then:
4095 main.FALSE if the given values are not in the set OR
4096 main.TRUE if the given values are in the set OR
4097 """
4098 try:
4099 values = str( values ).strip()
4100 setName = str( setName ).strip()
4101 length = len( values.split() )
4102 containsCheck = None
4103 # Patterns to match
4104 setPattern = "\[(.*)\]"
4105 pattern = "Items in set " + setName + ":\n" + setPattern
4106 containsTrue = "Set " + setName + " contains the value " + values
4107 containsFalse = "Set " + setName + " did not contain the value " +\
4108 values
4109 containsAllTrue = "Set " + setName + " contains the the subset " +\
4110 setPattern
4111 containsAllFalse = "Set " + setName + " did not contain the the" +\
4112 " subset " + setPattern
4113
4114 cmdStr = "set-test-get "
4115 cmdStr += setName + " " + values
4116 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004117 try:
Jon Halla495f562016-05-16 18:03:26 -07004118 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004119 # TODO: Maybe make this less hardcoded
4120 # ConsistentMap Exceptions
4121 assert "org.onosproject.store.service" not in output
4122 # Node not leader
4123 assert "java.lang.IllegalStateException" not in output
4124 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004125 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004126 "command: " + str( output ) )
4127 retryTime = 30 # Conservative time, given by Madan
4128 main.log.info( "Waiting " + str( retryTime ) +
4129 "seconds before retrying." )
4130 time.sleep( retryTime ) # Due to change in mastership
4131 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004132 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004133 assert "Command not found:" not in output, output
4134 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004135 main.log.info( self.name + ": " + output )
4136
4137 if length == 0:
4138 match = re.search( pattern, output )
4139 else: # if given values
4140 if length == 1: # Contains output
4141 patternTrue = pattern + "\n" + containsTrue
4142 patternFalse = pattern + "\n" + containsFalse
4143 else: # ContainsAll output
4144 patternTrue = pattern + "\n" + containsAllTrue
4145 patternFalse = pattern + "\n" + containsAllFalse
4146 matchTrue = re.search( patternTrue, output )
4147 matchFalse = re.search( patternFalse, output )
4148 if matchTrue:
4149 containsCheck = main.TRUE
4150 match = matchTrue
4151 elif matchFalse:
4152 containsCheck = main.FALSE
4153 match = matchFalse
4154 else:
4155 main.log.error( self.name + " setTestGet did not match " +\
4156 "expected output" )
4157 main.log.debug( self.name + " expected: " + pattern )
4158 main.log.debug( self.name + " actual: " + repr( output ) )
4159 match = None
4160 if match:
4161 setMatch = match.group( 1 )
4162 if setMatch == '':
4163 setList = []
4164 else:
4165 setList = setMatch.split( ", " )
4166 if length > 0:
4167 return ( setList, containsCheck )
4168 else:
4169 return setList
4170 else: # no match
4171 main.log.error( self.name + ": setTestGet did not" +
4172 " match expected output" )
4173 main.log.debug( self.name + " expected: " + pattern )
4174 main.log.debug( self.name + " actual: " + repr( output ) )
4175 return main.ERROR
4176 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004177 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004178 return main.ERROR
4179 except TypeError:
4180 main.log.exception( self.name + ": Object not as expected" )
4181 return main.ERROR
4182 except pexpect.EOF:
4183 main.log.error( self.name + ": EOF exception found" )
4184 main.log.error( self.name + ": " + self.handle.before )
4185 main.cleanup()
4186 main.exit()
4187 except Exception:
4188 main.log.exception( self.name + ": Uncaught exception!" )
4189 main.cleanup()
4190 main.exit()
4191
4192 def setTestSize( self, setName ):
4193 """
4194 CLI command to get the elements in a distributed set.
4195 Required arguments:
4196 setName - The name of the set to remove from.
4197 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004198 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004199 None on error
4200 """
4201 try:
4202 # TODO: Should this check against the number of elements returned
4203 # and then return true/false based on that?
4204 setName = str( setName ).strip()
4205 # Patterns to match
4206 setPattern = "\[(.*)\]"
4207 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4208 setPattern
4209 cmdStr = "set-test-get -s "
4210 cmdStr += setName
4211 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004212 try:
Jon Halla495f562016-05-16 18:03:26 -07004213 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004214 # TODO: Maybe make this less hardcoded
4215 # ConsistentMap Exceptions
4216 assert "org.onosproject.store.service" not in output
4217 # Node not leader
4218 assert "java.lang.IllegalStateException" not in output
4219 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004220 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004221 "command: " + str( output ) )
4222 retryTime = 30 # Conservative time, given by Madan
4223 main.log.info( "Waiting " + str( retryTime ) +
4224 "seconds before retrying." )
4225 time.sleep( retryTime ) # Due to change in mastership
4226 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004227 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004228 assert "Command not found:" not in output, output
4229 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004230 main.log.info( self.name + ": " + output )
4231 match = re.search( pattern, output )
4232 if match:
4233 setSize = int( match.group( 1 ) )
4234 setMatch = match.group( 2 )
4235 if len( setMatch.split() ) == setSize:
4236 main.log.info( "The size returned by " + self.name +
4237 " matches the number of elements in " +
4238 "the returned set" )
4239 else:
4240 main.log.error( "The size returned by " + self.name +
4241 " does not match the number of " +
4242 "elements in the returned set." )
4243 return setSize
4244 else: # no match
4245 main.log.error( self.name + ": setTestGet did not" +
4246 " match expected output" )
4247 main.log.debug( self.name + " expected: " + pattern )
4248 main.log.debug( self.name + " actual: " + repr( output ) )
4249 return None
4250 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004251 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004252 return None
Jon Hall390696c2015-05-05 17:13:41 -07004253 except TypeError:
4254 main.log.exception( self.name + ": Object not as expected" )
4255 return None
4256 except pexpect.EOF:
4257 main.log.error( self.name + ": EOF exception found" )
4258 main.log.error( self.name + ": " + self.handle.before )
4259 main.cleanup()
4260 main.exit()
4261 except Exception:
4262 main.log.exception( self.name + ": Uncaught exception!" )
4263 main.cleanup()
4264 main.exit()
4265
Jon Hall80daded2015-05-27 16:07:00 -07004266 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004267 """
4268 Command to list the various counters in the system.
4269 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004270 if jsonFormat, a string of the json object returned by the cli
4271 command
4272 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004273 None on error
4274 """
Jon Hall390696c2015-05-05 17:13:41 -07004275 try:
4276 counters = {}
4277 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004278 if jsonFormat:
4279 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004280 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004281 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004282 assert "Command not found:" not in output, output
4283 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004284 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004285 return output
Jon Hall390696c2015-05-05 17:13:41 -07004286 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004287 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004288 return None
Jon Hall390696c2015-05-05 17:13:41 -07004289 except TypeError:
4290 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004291 return None
Jon Hall390696c2015-05-05 17:13:41 -07004292 except pexpect.EOF:
4293 main.log.error( self.name + ": EOF exception found" )
4294 main.log.error( self.name + ": " + self.handle.before )
4295 main.cleanup()
4296 main.exit()
4297 except Exception:
4298 main.log.exception( self.name + ": Uncaught exception!" )
4299 main.cleanup()
4300 main.exit()
4301
Jon Hall935db192016-04-19 00:22:04 -07004302 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004303 """
Jon Halle1a3b752015-07-22 13:02:46 -07004304 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004305 Required arguments:
4306 counter - The name of the counter to increment.
4307 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004308 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004309 returns:
4310 integer value of the counter or
4311 None on Error
4312 """
4313 try:
4314 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004315 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004316 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004317 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004318 if delta != 1:
4319 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004320 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004321 try:
Jon Halla495f562016-05-16 18:03:26 -07004322 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004323 # TODO: Maybe make this less hardcoded
4324 # ConsistentMap Exceptions
4325 assert "org.onosproject.store.service" not in output
4326 # Node not leader
4327 assert "java.lang.IllegalStateException" not in output
4328 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004329 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004330 "command: " + str( output ) )
4331 retryTime = 30 # Conservative time, given by Madan
4332 main.log.info( "Waiting " + str( retryTime ) +
4333 "seconds before retrying." )
4334 time.sleep( retryTime ) # Due to change in mastership
4335 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004336 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004337 assert "Command not found:" not in output, output
4338 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004339 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004340 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004341 match = re.search( pattern, output )
4342 if match:
4343 return int( match.group( 1 ) )
4344 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004345 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004346 " match expected output." )
4347 main.log.debug( self.name + " expected: " + pattern )
4348 main.log.debug( self.name + " actual: " + repr( output ) )
4349 return None
4350 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004351 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004352 return None
4353 except TypeError:
4354 main.log.exception( self.name + ": Object not as expected" )
4355 return None
4356 except pexpect.EOF:
4357 main.log.error( self.name + ": EOF exception found" )
4358 main.log.error( self.name + ": " + self.handle.before )
4359 main.cleanup()
4360 main.exit()
4361 except Exception:
4362 main.log.exception( self.name + ": Uncaught exception!" )
4363 main.cleanup()
4364 main.exit()
4365
Jon Hall935db192016-04-19 00:22:04 -07004366 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004367 """
4368 CLI command to get a distributed counter then add a delta to it.
4369 Required arguments:
4370 counter - The name of the counter to increment.
4371 Optional arguments:
4372 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004373 returns:
4374 integer value of the counter or
4375 None on Error
4376 """
4377 try:
4378 counter = str( counter )
4379 delta = int( delta )
4380 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004381 cmdStr += counter
4382 if delta != 1:
4383 cmdStr += " " + str( delta )
4384 output = self.sendline( cmdStr )
4385 try:
Jon Halla495f562016-05-16 18:03:26 -07004386 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004387 # TODO: Maybe make this less hardcoded
4388 # ConsistentMap Exceptions
4389 assert "org.onosproject.store.service" not in output
4390 # Node not leader
4391 assert "java.lang.IllegalStateException" not in output
4392 except AssertionError:
4393 main.log.error( "Error in processing '" + cmdStr + "' " +
4394 "command: " + str( output ) )
4395 retryTime = 30 # Conservative time, given by Madan
4396 main.log.info( "Waiting " + str( retryTime ) +
4397 "seconds before retrying." )
4398 time.sleep( retryTime ) # Due to change in mastership
4399 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004400 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004401 assert "Command not found:" not in output, output
4402 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004403 main.log.info( self.name + ": " + output )
4404 pattern = counter + " was updated to (-?\d+)"
4405 match = re.search( pattern, output )
4406 if match:
4407 return int( match.group( 1 ) )
4408 else:
4409 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4410 " match expected output." )
4411 main.log.debug( self.name + " expected: " + pattern )
4412 main.log.debug( self.name + " actual: " + repr( output ) )
4413 return None
4414 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004415 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004416 return None
4417 except TypeError:
4418 main.log.exception( self.name + ": Object not as expected" )
4419 return None
4420 except pexpect.EOF:
4421 main.log.error( self.name + ": EOF exception found" )
4422 main.log.error( self.name + ": " + self.handle.before )
4423 main.cleanup()
4424 main.exit()
4425 except Exception:
4426 main.log.exception( self.name + ": Uncaught exception!" )
4427 main.cleanup()
4428 main.exit()
4429
YPZhangfebf7302016-05-24 16:45:56 -07004430 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004431 """
4432 Description: Execute summary command in onos
4433 Returns: json object ( summary -j ), returns main.FALSE if there is
4434 no output
4435
4436 """
4437 try:
4438 cmdStr = "summary"
4439 if jsonFormat:
4440 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004441 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004442 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004443 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004444 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004445 if not handle:
4446 main.log.error( self.name + ": There is no output in " +
4447 "summary command" )
4448 return main.FALSE
4449 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004450 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004451 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004452 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004453 except TypeError:
4454 main.log.exception( self.name + ": Object not as expected" )
4455 return None
4456 except pexpect.EOF:
4457 main.log.error( self.name + ": EOF exception found" )
4458 main.log.error( self.name + ": " + self.handle.before )
4459 main.cleanup()
4460 main.exit()
4461 except Exception:
4462 main.log.exception( self.name + ": Uncaught exception!" )
4463 main.cleanup()
4464 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004465
Jon Hall935db192016-04-19 00:22:04 -07004466 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004467 """
4468 CLI command to get the value of a key in a consistent map using
4469 transactions. This a test function and can only get keys from the
4470 test map hard coded into the cli command
4471 Required arguments:
4472 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004473 returns:
4474 The string value of the key or
4475 None on Error
4476 """
4477 try:
4478 keyName = str( keyName )
4479 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004480 cmdStr += keyName
4481 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004482 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004483 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004484 try:
4485 # TODO: Maybe make this less hardcoded
4486 # ConsistentMap Exceptions
4487 assert "org.onosproject.store.service" not in output
4488 # Node not leader
4489 assert "java.lang.IllegalStateException" not in output
4490 except AssertionError:
4491 main.log.error( "Error in processing '" + cmdStr + "' " +
4492 "command: " + str( output ) )
4493 return None
4494 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4495 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004496 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004497 return None
4498 else:
4499 match = re.search( pattern, output )
4500 if match:
4501 return match.groupdict()[ 'value' ]
4502 else:
4503 main.log.error( self.name + ": transactionlMapGet did not" +
4504 " match expected output." )
4505 main.log.debug( self.name + " expected: " + pattern )
4506 main.log.debug( self.name + " actual: " + repr( output ) )
4507 return None
Jon Hallc6793552016-01-19 14:18:37 -08004508 except AssertionError:
4509 main.log.exception( "" )
4510 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004511 except TypeError:
4512 main.log.exception( self.name + ": Object not as expected" )
4513 return None
4514 except pexpect.EOF:
4515 main.log.error( self.name + ": EOF exception found" )
4516 main.log.error( self.name + ": " + self.handle.before )
4517 main.cleanup()
4518 main.exit()
4519 except Exception:
4520 main.log.exception( self.name + ": Uncaught exception!" )
4521 main.cleanup()
4522 main.exit()
4523
Jon Hall935db192016-04-19 00:22:04 -07004524 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004525 """
4526 CLI command to put a value into 'numKeys' number of keys in a
4527 consistent map using transactions. This a test function and can only
4528 put into keys named 'Key#' of the test map hard coded into the cli command
4529 Required arguments:
4530 numKeys - Number of keys to add the value to
4531 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004532 returns:
4533 A dictionary whose keys are the name of the keys put into the map
4534 and the values of the keys are dictionaries whose key-values are
4535 'value': value put into map and optionaly
4536 'oldValue': Previous value in the key or
4537 None on Error
4538
4539 Example output
4540 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4541 'Key2': {'value': 'Testing'} }
4542 """
4543 try:
4544 numKeys = str( numKeys )
4545 value = str( value )
4546 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004547 cmdStr += numKeys + " " + value
4548 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004549 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004550 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004551 try:
4552 # TODO: Maybe make this less hardcoded
4553 # ConsistentMap Exceptions
4554 assert "org.onosproject.store.service" not in output
4555 # Node not leader
4556 assert "java.lang.IllegalStateException" not in output
4557 except AssertionError:
4558 main.log.error( "Error in processing '" + cmdStr + "' " +
4559 "command: " + str( output ) )
4560 return None
4561 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4562 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4563 results = {}
4564 for line in output.splitlines():
4565 new = re.search( newPattern, line )
4566 updated = re.search( updatedPattern, line )
4567 if new:
4568 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4569 elif updated:
4570 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004571 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004572 else:
4573 main.log.error( self.name + ": transactionlMapGet did not" +
4574 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004575 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4576 newPattern,
4577 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 main.log.debug( self.name + " actual: " + repr( output ) )
4579 return results
Jon Hallc6793552016-01-19 14:18:37 -08004580 except AssertionError:
4581 main.log.exception( "" )
4582 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004583 except TypeError:
4584 main.log.exception( self.name + ": Object not as expected" )
4585 return None
4586 except pexpect.EOF:
4587 main.log.error( self.name + ": EOF exception found" )
4588 main.log.error( self.name + ": " + self.handle.before )
4589 main.cleanup()
4590 main.exit()
4591 except Exception:
4592 main.log.exception( self.name + ": Uncaught exception!" )
4593 main.cleanup()
4594 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004595
acsmarsdaea66c2015-09-03 11:44:06 -07004596 def maps( self, jsonFormat=True ):
4597 """
4598 Description: Returns result of onos:maps
4599 Optional:
4600 * jsonFormat: enable json formatting of output
4601 """
4602 try:
4603 cmdStr = "maps"
4604 if jsonFormat:
4605 cmdStr += " -j"
4606 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004607 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004608 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004609 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004610 except AssertionError:
4611 main.log.exception( "" )
4612 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004613 except TypeError:
4614 main.log.exception( self.name + ": Object not as expected" )
4615 return None
4616 except pexpect.EOF:
4617 main.log.error( self.name + ": EOF exception found" )
4618 main.log.error( self.name + ": " + self.handle.before )
4619 main.cleanup()
4620 main.exit()
4621 except Exception:
4622 main.log.exception( self.name + ": Uncaught exception!" )
4623 main.cleanup()
4624 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004625
4626 def getSwController( self, uri, jsonFormat=True ):
4627 """
4628 Descrition: Gets the controller information from the device
4629 """
4630 try:
4631 cmd = "device-controllers "
4632 if jsonFormat:
4633 cmd += "-j "
4634 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004635 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004636 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004637 return response
Jon Hallc6793552016-01-19 14:18:37 -08004638 except AssertionError:
4639 main.log.exception( "" )
4640 return None
GlennRC050596c2015-11-18 17:06:41 -08004641 except TypeError:
4642 main.log.exception( self.name + ": Object not as expected" )
4643 return None
4644 except pexpect.EOF:
4645 main.log.error( self.name + ": EOF exception found" )
4646 main.log.error( self.name + ": " + self.handle.before )
4647 main.cleanup()
4648 main.exit()
4649 except Exception:
4650 main.log.exception( self.name + ": Uncaught exception!" )
4651 main.cleanup()
4652 main.exit()
4653
4654 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4655 """
4656 Descrition: sets the controller(s) for the specified device
4657
4658 Parameters:
4659 Required: uri - String: The uri of the device(switch).
4660 ip - String or List: The ip address of the controller.
4661 This parameter can be formed in a couple of different ways.
4662 VALID:
4663 10.0.0.1 - just the ip address
4664 tcp:10.0.0.1 - the protocol and the ip address
4665 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4666 so that you can add controllers with different
4667 protocols and ports
4668 INVALID:
4669 10.0.0.1:6653 - this is not supported by ONOS
4670
4671 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4672 port - The port number.
4673 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4674
4675 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4676 """
4677 try:
4678 cmd = "device-setcontrollers"
4679
4680 if jsonFormat:
4681 cmd += " -j"
4682 cmd += " " + uri
4683 if isinstance( ip, str ):
4684 ip = [ip]
4685 for item in ip:
4686 if ":" in item:
4687 sitem = item.split( ":" )
4688 if len(sitem) == 3:
4689 cmd += " " + item
4690 elif "." in sitem[1]:
4691 cmd += " {}:{}".format(item, port)
4692 else:
4693 main.log.error( "Malformed entry: " + item )
4694 raise TypeError
4695 else:
4696 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004697 response = self.sendline( cmd )
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
GlennRC050596c2015-11-18 17:06:41 -08004700 if "Error" in response:
4701 main.log.error( response )
4702 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004703 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004704 except AssertionError:
4705 main.log.exception( "" )
4706 return None
GlennRC050596c2015-11-18 17:06:41 -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()
GlennRC20fc6522015-12-23 23:26:57 -08004719
4720 def removeDevice( self, device ):
4721 '''
4722 Description:
4723 Remove a device from ONOS by passing the uri of the device(s).
4724 Parameters:
4725 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
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( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004734 deviceStr = device
4735 device = []
4736 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004737
4738 for d in device:
4739 time.sleep( 1 )
4740 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004741 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004742 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004743 if "Error" in response:
4744 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4745 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004746 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004747 except AssertionError:
4748 main.log.exception( "" )
4749 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004750 except TypeError:
4751 main.log.exception( self.name + ": Object not as expected" )
4752 return main.FALSE
4753 except pexpect.EOF:
4754 main.log.error( self.name + ": EOF exception found" )
4755 main.log.error( self.name + ": " + self.handle.before )
4756 main.cleanup()
4757 main.exit()
4758 except Exception:
4759 main.log.exception( self.name + ": Uncaught exception!" )
4760 main.cleanup()
4761 main.exit()
4762
4763 def removeHost( self, host ):
4764 '''
4765 Description:
4766 Remove a host from ONOS by passing the id of the host(s)
4767 Parameters:
4768 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4769 Returns:
4770 Returns main.FALSE if an exception is thrown or an error is present
4771 in the response. Otherwise, returns main.TRUE.
4772 NOTE:
4773 If a host cannot be removed, then this function will return main.FALSE
4774 '''
4775 try:
4776 if type( host ) is str:
4777 host = list( host )
4778
4779 for h in host:
4780 time.sleep( 1 )
4781 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004782 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004783 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004784 if "Error" in response:
4785 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4786 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004787 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004788 except AssertionError:
4789 main.log.exception( "" )
4790 return None
GlennRC20fc6522015-12-23 23:26:57 -08004791 except TypeError:
4792 main.log.exception( self.name + ": Object not as expected" )
4793 return main.FALSE
4794 except pexpect.EOF:
4795 main.log.error( self.name + ": EOF exception found" )
4796 main.log.error( self.name + ": " + self.handle.before )
4797 main.cleanup()
4798 main.exit()
4799 except Exception:
4800 main.log.exception( self.name + ": Uncaught exception!" )
4801 main.cleanup()
4802 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004803
YPZhangfebf7302016-05-24 16:45:56 -07004804 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004805 '''
4806 Description:
4807 Bring link down or up in the null-provider.
4808 params:
4809 begin - (string) One end of a device or switch.
4810 end - (string) the other end of the device or switch
4811 returns:
4812 main.TRUE if no exceptions were thrown and no Errors are
4813 present in the resoponse. Otherwise, returns main.FALSE
4814 '''
4815 try:
Jon Hallc6793552016-01-19 14:18:37 -08004816 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004817 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004818 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004819 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004820 if "Error" in response or "Failure" in response:
4821 main.log.error( response )
4822 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004823 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004824 except AssertionError:
4825 main.log.exception( "" )
4826 return None
GlennRCed771242016-01-13 17:02:47 -08004827 except TypeError:
4828 main.log.exception( self.name + ": Object not as expected" )
4829 return main.FALSE
4830 except pexpect.EOF:
4831 main.log.error( self.name + ": EOF exception found" )
4832 main.log.error( self.name + ": " + self.handle.before )
4833 main.cleanup()
4834 main.exit()
4835 except Exception:
4836 main.log.exception( self.name + ": Uncaught exception!" )
4837 main.cleanup()
4838 main.exit()
4839
Flavio Castro82ee2f62016-06-07 15:04:12 -07004840 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4841 '''
4842 Description:
4843 Changes the state of port in an OF switch by means of the
4844 PORTSTATUS OF messages.
4845 params:
4846 dpid - (string) Datapath ID of the device
4847 port - (string) target port in the device
4848 state - (string) target state (enable or disabled)
4849 returns:
4850 main.TRUE if no exceptions were thrown and no Errors are
4851 present in the resoponse. Otherwise, returns main.FALSE
4852 '''
4853 try:
4854 cmd = "portstate {} {} {}".format( dpid, port, state )
4855 response = self.sendline( cmd, showResponse=True )
4856 assert response is not None, "Error in sendline"
4857 assert "Command not found:" not in response, response
4858 if "Error" in response or "Failure" in response:
4859 main.log.error( response )
4860 return main.FALSE
4861 return main.TRUE
4862 except AssertionError:
4863 main.log.exception( "" )
4864 return None
4865 except TypeError:
4866 main.log.exception( self.name + ": Object not as expected" )
4867 return main.FALSE
4868 except pexpect.EOF:
4869 main.log.error( self.name + ": EOF exception found" )
4870 main.log.error( self.name + ": " + self.handle.before )
4871 main.cleanup()
4872 main.exit()
4873 except Exception:
4874 main.log.exception( self.name + ": Uncaught exception!" )
4875 main.cleanup()
4876 main.exit()
4877
4878 def logSet( self, level="INFO", app="org.onosproject" ):
4879 """
4880 Set the logging level to lvl for a specific app
4881 returns main.TRUE on success
4882 returns main.FALSE if Error occurred
4883 if noExit is True, TestON will not exit, but clean up
4884 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4885 Level defaults to INFO
4886 """
4887 try:
4888 self.handle.sendline( "log:set %s %s" %( level, app ) )
4889 self.handle.expect( "onos>" )
4890
4891 response = self.handle.before
4892 if re.search( "Error", response ):
4893 return main.FALSE
4894 return main.TRUE
4895 except pexpect.TIMEOUT:
4896 main.log.exception( self.name + ": TIMEOUT exception found" )
4897 main.cleanup()
4898 main.exit()
4899 except pexpect.EOF:
4900 main.log.error( self.name + ": EOF exception found" )
4901 main.log.error( self.name + ": " + self.handle.before )
4902 main.cleanup()
4903 main.exit()
4904 except Exception:
4905 main.log.exception( self.name + ": Uncaught exception!" )
4906 main.cleanup()
4907 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004908
4909 def getGraphDict( self, timeout=60, includeHost=False ):
4910 """
4911 Return a dictionary which describes the latest network topology data as a
4912 graph.
4913 An example of the dictionary:
4914 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4915 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4916 Each vertex should at least have an 'edges' attribute which describes the
4917 adjacency information. The value of 'edges' attribute is also represented by
4918 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4919 list of attributes.
4920 An example of the edges dictionary:
4921 'edges': { vertex2: { 'port': ..., 'weight': ... },
4922 vertex3: { 'port': ..., 'weight': ... } }
4923 If includeHost == True, all hosts (and host-switch links) will be included
4924 in topology data.
4925 """
4926 graphDict = {}
4927 try:
4928 links = self.links()
4929 links = json.loads( links )
4930 devices = self.devices()
4931 devices = json.loads( devices )
4932 idToDevice = {}
4933 for device in devices:
4934 idToDevice[ device[ 'id' ] ] = device
4935 if includeHost:
4936 hosts = self.hosts()
4937 # FIXME: support 'includeHost' argument
4938 for link in links:
4939 nodeA = link[ 'src' ][ 'device' ]
4940 nodeB = link[ 'dst' ][ 'device' ]
4941 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4942 if not nodeA in graphDict.keys():
4943 graphDict[ nodeA ] = { 'edges':{},
4944 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4945 'type':idToDevice[ nodeA ][ 'type' ],
4946 'available':idToDevice[ nodeA ][ 'available' ],
4947 'role':idToDevice[ nodeA ][ 'role' ],
4948 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4949 'hw':idToDevice[ nodeA ][ 'hw' ],
4950 'sw':idToDevice[ nodeA ][ 'sw' ],
4951 'serial':idToDevice[ nodeA ][ 'serial' ],
4952 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4953 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4954 else:
4955 # Assert nodeB is not connected to any current links of nodeA
4956 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4957 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4958 'type':link[ 'type' ],
4959 'state':link[ 'state' ] }
4960 return graphDict
4961 except ( TypeError, ValueError ):
4962 main.log.exception( self.name + ": Object not as expected" )
4963 return None
4964 except KeyError:
4965 main.log.exception( self.name + ": KeyError exception found" )
4966 return None
4967 except AssertionError:
4968 main.log.exception( self.name + ": AssertionError exception found" )
4969 return None
4970 except pexpect.EOF:
4971 main.log.error( self.name + ": EOF exception found" )
4972 main.log.error( self.name + ": " + self.handle.before )
4973 return None
4974 except Exception:
4975 main.log.exception( self.name + ": Uncaught exception!" )
4976 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004977
4978 def getIntentPerfSummary( self ):
4979 '''
4980 Send command to check intent-perf summary
4981 Returns: dictionary for intent-perf summary
4982 if something wrong, function will return None
4983 '''
4984 cmd = "intent-perf -s"
4985 respDic = {}
4986 resp = self.sendline( cmd )
4987 try:
4988 # Generate the dictionary to return
4989 for l in resp.split( "\n" ):
4990 # Delete any white space in line
4991 temp = re.sub( r'\s+', '', l )
4992 temp = temp.split( ":" )
4993 respDic[ temp[0] ] = temp[ 1 ]
4994
4995 except (TypeError, ValueError):
4996 main.log.exception( self.name + ": Object not as expected" )
4997 return None
4998 except KeyError:
4999 main.log.exception( self.name + ": KeyError exception found" )
5000 return None
5001 except AssertionError:
5002 main.log.exception( self.name + ": AssertionError exception found" )
5003 return None
5004 except pexpect.EOF:
5005 main.log.error( self.name + ": EOF exception found" )
5006 main.log.error( self.name + ": " + self.handle.before )
5007 return None
5008 except Exception:
5009 main.log.exception( self.name + ": Uncaught exception!" )
5010 return None
5011 return respDic
5012
chengchiyu08303a02016-09-08 17:40:26 -07005013 def logSearch( self, searchTerm, mode='all' ):
5014 """
5015 Searches the latest ONOS log file for the given search term and
5016 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005017
chengchiyu08303a02016-09-08 17:40:26 -07005018 Arguments:
5019 searchTerm - A string to grep for in the ONOS log.
5020 mode:
5021 all: return all the strings that contain the search term
5022 last: return the last string that contains the search term
5023 first: return the first string that contains the search term
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005024 num: return the number that the searchTerm appears in the log
chengchiyu08303a02016-09-08 17:40:26 -07005025 """
5026 try:
5027 assert type( searchTerm ) is str
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005028 cmd = "cat /opt/onos/log/karaf.log | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005029 if mode == 'last':
5030 cmd = cmd + " | tail -n 1"
5031 if mode == 'first':
5032 cmd = cmd + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005033 if mode == 'num':
5034 cmd = "cat /opt/onos/log/karaf.log | grep -c \'" + searchTerm + "\'"
5035 num = self.sendline( cmd )
5036 return num
chengchiyu08303a02016-09-08 17:40:26 -07005037 before = self.sendline( cmd )
5038 before = before.splitlines()
5039 # make sure the returned list only contains the search term
5040 returnLines = [line for line in before if searchTerm in line]
5041 return returnLines
5042 except AssertionError:
5043 main.log.error( self.name + " searchTerm is not string type" )
5044 return None
5045 except pexpect.EOF:
5046 main.log.error( self.name + ": EOF exception found" )
5047 main.log.error( self.name + ": " + self.handle.before )
5048 main.cleanup()
5049 main.exit()
5050 except pexpect.TIMEOUT:
5051 main.log.error( self.name + ": TIMEOUT exception found" )
5052 main.log.error( self.name + ": " + self.handle.before )
5053 main.cleanup()
5054 main.exit()
5055 except Exception:
5056 main.log.exception( self.name + ": Uncaught exception!" )
5057 main.cleanup()
5058 main.exit()