blob: 4052db2b65c3c7d19825550b1afffb8123e832c6 [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:
Jon Hall67253832016-12-05 09:47:13 -0800252 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.sendline( "" )
254 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500256 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
Jon Hall67253832016-12-05 09:47:13 -0800260 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800261 if waitForStart:
262 # Wait for onos start ( -w ) and enter onos cli
263 startCliCommand = "onos -w "
264 else:
265 startCliCommand = "onos "
266 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800267 i = self.handle.expect( [
268 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700269 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400270
271 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800273 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800275 "config:property-set -p org.apache.karaf.shell\
276 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800277 karafTimeout )
278 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800279 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800280 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400281 return main.TRUE
282 else:
kelvin8ec71442015-01-15 16:57:00 -0800283 # If failed, send ctrl+c to process and try again
284 main.log.info( "Starting CLI failed. Retrying..." )
285 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
288 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800290 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800291 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800292 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 "config:property-set -p org.apache.karaf.shell\
295 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800296 karafTimeout )
297 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400300 return main.TRUE
301 else:
kelvin8ec71442015-01-15 16:57:00 -0800302 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800303 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400304 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400305
Jon Halld4d4b372015-01-28 16:02:41 -0800306 except TypeError:
307 main.log.exception( self.name + ": Object not as expected" )
308 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800310 main.log.error( self.name + ": EOF exception found" )
311 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400312 main.cleanup()
313 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800314 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400316 main.cleanup()
317 main.exit()
318
suibin zhang116647a2016-05-06 16:30:09 -0700319 def startCellCli( self, karafTimeout="",
320 commandlineTimeout=10, onosStartTimeout=60 ):
321 """
322 Start CLI on onos ecll handle.
323
324 karafTimeout is an optional argument. karafTimeout value passed
325 by user would be used to set the current karaf shell idle timeout.
326 Note that when ever this property is modified the shell will exit and
327 the subsequent login would reflect new idle timeout.
328 Below is an example to start a session with 60 seconds idle timeout
329 ( input value is in milliseconds ):
330
331 tValue = "60000"
332
333 Note: karafTimeout is left as str so that this could be read
334 and passed to startOnosCli from PARAMS file as str.
335 """
336
337 try:
338 self.handle.sendline( "" )
339 x = self.handle.expect( [
340 "\$", "onos>" ], commandlineTimeout)
341
342 if x == 1:
343 main.log.info( "ONOS cli is already running" )
344 return main.TRUE
345
346 # Wait for onos start ( -w ) and enter onos cli
347 self.handle.sendline( "/opt/onos/bin/onos" )
348 i = self.handle.expect( [
349 "onos>",
350 pexpect.TIMEOUT ], onosStartTimeout )
351
352 if i == 0:
353 main.log.info( self.name + " CLI Started successfully" )
354 if karafTimeout:
355 self.handle.sendline(
356 "config:property-set -p org.apache.karaf.shell\
357 sshIdleTimeout " +
358 karafTimeout )
359 self.handle.expect( "\$" )
360 self.handle.sendline( "/opt/onos/bin/onos" )
361 self.handle.expect( "onos>" )
362 return main.TRUE
363 else:
364 # If failed, send ctrl+c to process and try again
365 main.log.info( "Starting CLI failed. Retrying..." )
366 self.handle.send( "\x03" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
369 timeout=30 )
370 if i == 0:
371 main.log.info( self.name + " CLI Started " +
372 "successfully after retry attempt" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
378 self.handle.expect( "\$" )
379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 main.log.error( "Connection to CLI " +
384 self.name + " timeout" )
385 return main.FALSE
386
387 except TypeError:
388 main.log.exception( self.name + ": Object not as expected" )
389 return None
390 except pexpect.EOF:
391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
393 main.cleanup()
394 main.exit()
395 except Exception:
396 main.log.exception( self.name + ": Uncaught exception!" )
397 main.cleanup()
398 main.exit()
399
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800400 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800401 """
402 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800403 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800404 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700405 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800406 Available level: DEBUG, TRACE, INFO, WARN, ERROR
407 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800408 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800409 """
410 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800411 lvlStr = ""
412 if level:
413 lvlStr = "--level=" + level
414
kelvin-onlab338f5512015-02-06 10:53:16 -0800415 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700416 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800418
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 response = self.handle.before
420 if re.search( "Error", response ):
421 return main.FALSE
422 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700423 except pexpect.TIMEOUT:
424 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit:
426 main.cleanup()
427 return None
428 else:
429 main.cleanup()
430 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800431 except pexpect.EOF:
432 main.log.error( self.name + ": EOF exception found" )
433 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700434 if noExit:
435 main.cleanup()
436 return None
437 else:
438 main.cleanup()
439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800440 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800441 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
446 main.cleanup()
447 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400448
YPZhangebf9eb52016-05-12 15:20:24 -0700449 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800451 Send a completely user specified string to
452 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400453 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800454
YPZhang14a4aa92016-07-15 13:37:15 -0700455 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700456
andrewonlaba18f6bf2014-10-13 19:31:54 -0400457 Warning: There are no sanity checking to commands
458 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800459
kelvin8ec71442015-01-15 16:57:00 -0800460 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400461 try:
Jon Halla495f562016-05-16 18:03:26 -0700462 # Try to reconnect if disconnected from cli
463 self.handle.sendline( "" )
464 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
465 if i == 1:
466 main.log.error( self.name + ": onos cli session closed. ")
467 if self.onosIp:
468 main.log.warn( "Trying to reconnect " + self.onosIp )
469 reconnectResult = self.startOnosCli( self.onosIp )
470 if reconnectResult:
471 main.log.info( self.name + ": onos cli session reconnected." )
472 else:
473 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700474 if noExit:
475 return None
476 else:
477 main.cleanup()
478 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700479 else:
480 main.cleanup()
481 main.exit()
482 if i == 2:
483 self.handle.sendline( "" )
484 self.handle.expect( "onos>" )
485
Jon Hall14a03b52016-05-11 12:07:30 -0700486 if debug:
487 # NOTE: This adds and average of .4 seconds per call
488 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700489 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800490 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800491 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800492 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800493 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800494 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
495 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700496 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700497 main.log.debug( self.name + ": Raw output" )
498 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700499
500 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800501 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800502 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700504 main.log.debug( self.name + ": ansiEscape output" )
505 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700506
kelvin-onlabfb521662015-02-27 09:52:40 -0800507 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800508 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700509 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700510 main.log.debug( self.name + ": Removed extra returns " +
511 "from output" )
512 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700513
514 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800515 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700516 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700517 main.log.debug( self.name + ": parsed and stripped output" )
518 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700519
Jon Hall63604932015-02-26 17:09:50 -0800520 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 output = response.split( cmdStr.strip(), 1 )
522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700525 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800526 output = output[1].strip()
527 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800528 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800529 return output
GlennRCed771242016-01-13 17:02:47 -0800530 except pexpect.TIMEOUT:
531 main.log.error( self.name + ":ONOS timeout" )
532 if debug:
533 main.log.debug( self.handle.before )
534 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 except IndexError:
536 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700537 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800539 except TypeError:
540 main.log.exception( self.name + ": Object not as expected" )
541 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400542 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800543 main.log.error( self.name + ": EOF exception found" )
544 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700545 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700546 return None
547 else:
548 main.cleanup()
549 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800551 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700552 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700553 return None
554 else:
555 main.cleanup()
556 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400557
kelvin8ec71442015-01-15 16:57:00 -0800558 # IMPORTANT NOTE:
559 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800560 # the cli command changing 'a:b' with 'aB'.
561 # Ex ) onos:topology > onosTopology
562 # onos:links > onosLinks
563 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800564
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800566 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400567 Adds a new cluster node by ID and address information.
568 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 * nodeId
570 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400571 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800572 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800573 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400574 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800575 cmdStr = "add-node " + str( nodeId ) + " " +\
576 str( ONOSIp ) + " " + str( tcpPort )
577 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700578 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800579 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800580 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800581 main.log.error( "Error in adding node" )
582 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800583 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800587 except AssertionError:
588 main.log.exception( "" )
589 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800590 except TypeError:
591 main.log.exception( self.name + ": Object not as expected" )
592 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800594 main.log.error( self.name + ": EOF exception found" )
595 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400596 main.cleanup()
597 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800598 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800599 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 main.cleanup()
601 main.exit()
602
kelvin-onlabd3b64892015-01-20 13:26:24 -0800603 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800604 """
andrewonlab86dc3082014-10-13 18:18:38 -0400605 Removes a cluster by ID
606 Issues command: 'remove-node [<node-id>]'
607 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800609 """
andrewonlab86dc3082014-10-13 18:18:38 -0400610 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400611
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700613 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700614 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800615 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700616 if re.search( "Error", handle ):
617 main.log.error( "Error in removing node" )
618 main.log.error( handle )
619 return main.FALSE
620 else:
621 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800622 except AssertionError:
623 main.log.exception( "" )
624 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800625 except TypeError:
626 main.log.exception( self.name + ": Object not as expected" )
627 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400628 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800629 main.log.error( self.name + ": EOF exception found" )
630 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400631 main.cleanup()
632 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800633 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800634 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400635 main.cleanup()
636 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400637
Jon Hall61282e32015-03-19 11:34:11 -0700638 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800639 """
andrewonlab7c211572014-10-15 16:45:20 -0400640 List the nodes currently visible
641 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700642 Optional argument:
643 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800644 """
andrewonlab7c211572014-10-15 16:45:20 -0400645 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700646 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700647 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700648 cmdStr += " -j"
649 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700650 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800651 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700652 return output
Jon Hallc6793552016-01-19 14:18:37 -0800653 except AssertionError:
654 main.log.exception( "" )
655 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800656 except TypeError:
657 main.log.exception( self.name + ": Object not as expected" )
658 return None
andrewonlab7c211572014-10-15 16:45:20 -0400659 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800660 main.log.error( self.name + ": EOF exception found" )
661 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400662 main.cleanup()
663 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800665 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400666 main.cleanup()
667 main.exit()
668
kelvin8ec71442015-01-15 16:57:00 -0800669 def topology( self ):
670 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700671 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700672 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700673 Return:
674 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800675 """
andrewonlab95ce8322014-10-13 14:12:04 -0400676 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700677 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800679 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800680 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700681 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400682 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800683 except AssertionError:
684 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800685 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800686 except TypeError:
687 main.log.exception( self.name + ": Object not as expected" )
688 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400689 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800690 main.log.error( self.name + ": EOF exception found" )
691 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400692 main.cleanup()
693 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800694 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800695 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400696 main.cleanup()
697 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800698
jenkins7ead5a82015-03-13 10:28:21 -0700699 def deviceRemove( self, deviceId ):
700 """
701 Removes particular device from storage
702
703 TODO: refactor this function
704 """
705 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 cmdStr = "device-remove " + str( deviceId )
707 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800708 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800709 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700710 if re.search( "Error", handle ):
711 main.log.error( "Error in removing device" )
712 main.log.error( handle )
713 return main.FALSE
714 else:
715 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800716 except AssertionError:
717 main.log.exception( "" )
718 return None
jenkins7ead5a82015-03-13 10:28:21 -0700719 except TypeError:
720 main.log.exception( self.name + ": Object not as expected" )
721 return None
722 except pexpect.EOF:
723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
725 main.cleanup()
726 main.exit()
727 except Exception:
728 main.log.exception( self.name + ": Uncaught exception!" )
729 main.cleanup()
730 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800733 """
Jon Hall7b02d952014-10-17 20:14:54 -0400734 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400735 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800737 """
andrewonlab86dc3082014-10-13 18:18:38 -0400738 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 cmdStr += " -j"
742 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800743 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800744 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800746 except AssertionError:
747 main.log.exception( "" )
748 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800749 except TypeError:
750 main.log.exception( self.name + ": Object not as expected" )
751 return None
andrewonlab7c211572014-10-15 16:45:20 -0400752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800753 main.log.error( self.name + ": EOF exception found" )
754 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400755 main.cleanup()
756 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800757 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800758 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400759 main.cleanup()
760 main.exit()
761
kelvin-onlabd3b64892015-01-20 13:26:24 -0800762 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800763 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800764 This balances the devices across all controllers
765 by issuing command: 'onos> onos:balance-masters'
766 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800767 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700770 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800771 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800772 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700773 if re.search( "Error", handle ):
774 main.log.error( "Error in balancing masters" )
775 main.log.error( handle )
776 return main.FALSE
777 else:
778 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800779 except AssertionError:
780 main.log.exception( "" )
781 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800782 except TypeError:
783 main.log.exception( self.name + ": Object not as expected" )
784 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800785 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800786 main.log.error( self.name + ": EOF exception found" )
787 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800788 main.cleanup()
789 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800790 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800791 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800792 main.cleanup()
793 main.exit()
794
Jon Hallc6793552016-01-19 14:18:37 -0800795 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700796 """
797 Returns the output of the masters command.
798 Optional argument:
799 * jsonFormat - boolean indicating if you want output in json
800 """
801 try:
802 cmdStr = "onos:masters"
803 if jsonFormat:
804 cmdStr += " -j"
805 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700806 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800807 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700808 return output
Jon Hallc6793552016-01-19 14:18:37 -0800809 except AssertionError:
810 main.log.exception( "" )
811 return None
acsmars24950022015-07-30 18:00:43 -0700812 except TypeError:
813 main.log.exception( self.name + ": Object not as expected" )
814 return None
815 except pexpect.EOF:
816 main.log.error( self.name + ": EOF exception found" )
817 main.log.error( self.name + ": " + self.handle.before )
818 main.cleanup()
819 main.exit()
820 except Exception:
821 main.log.exception( self.name + ": Uncaught exception!" )
822 main.cleanup()
823 main.exit()
824
Jon Hallc6793552016-01-19 14:18:37 -0800825 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700826 """
827 Uses the master command to check that the devices' leadership
828 is evenly divided
829
830 Dependencies: checkMasters() and summary()
831
Jon Hall6509dbf2016-06-21 17:01:17 -0700832 Returns main.TRUE if the devices are balanced
833 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700834 Exits on Exception
835 Returns None on TypeError
836 """
837 try:
Jon Hallc6793552016-01-19 14:18:37 -0800838 summaryOutput = self.summary()
839 totalDevices = json.loads( summaryOutput )[ "devices" ]
840 except ( TypeError, ValueError ):
841 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
842 return None
843 try:
acsmars24950022015-07-30 18:00:43 -0700844 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800845 mastersOutput = self.checkMasters()
846 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700847 first = masters[ 0 ][ "size" ]
848 for master in masters:
849 totalOwnedDevices += master[ "size" ]
850 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
851 main.log.error( "Mastership not balanced" )
852 main.log.info( "\n" + self.checkMasters( False ) )
853 return main.FALSE
854 main.log.info( "Mastership balanced between " \
855 + str( len(masters) ) + " masters" )
856 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800857 except ( TypeError, ValueError ):
858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700859 return None
860 except pexpect.EOF:
861 main.log.error( self.name + ": EOF exception found" )
862 main.log.error( self.name + ": " + self.handle.before )
863 main.cleanup()
864 main.exit()
865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
867 main.cleanup()
868 main.exit()
869
YPZhangfebf7302016-05-24 16:45:56 -0700870 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800871 """
Jon Halle8217482014-10-17 13:49:14 -0400872 Lists all core links
873 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800875 """
Jon Halle8217482014-10-17 13:49:14 -0400876 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800878 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700879 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700880 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800881 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800882 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700883 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800884 except AssertionError:
885 main.log.exception( "" )
886 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800887 except TypeError:
888 main.log.exception( self.name + ": Object not as expected" )
889 return None
Jon Halle8217482014-10-17 13:49:14 -0400890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800891 main.log.error( self.name + ": EOF exception found" )
892 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400893 main.cleanup()
894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400897 main.cleanup()
898 main.exit()
899
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Halle8217482014-10-17 13:49:14 -0400902 Lists all ports
903 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800905 """
Jon Halle8217482014-10-17 13:49:14 -0400906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700907 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr += " -j"
910 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800911 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800912 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700913 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800914 except AssertionError:
915 main.log.exception( "" )
916 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800917 except TypeError:
918 main.log.exception( self.name + ": Object not as expected" )
919 return None
Jon Halle8217482014-10-17 13:49:14 -0400920 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800921 main.log.error( self.name + ": EOF exception found" )
922 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400923 main.cleanup()
924 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800926 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400927 main.cleanup()
928 main.exit()
929
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800931 """
Jon Hall983a1702014-10-28 18:44:22 -0400932 Lists all devices and the controllers with roles assigned to them
933 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800935 """
andrewonlab7c211572014-10-15 16:45:20 -0400936 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700939 cmdStr += " -j"
940 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800941 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800942 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700943 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800944 except AssertionError:
945 main.log.exception( "" )
946 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800947 except TypeError:
948 main.log.exception( self.name + ": Object not as expected" )
949 return None
Jon Hall983a1702014-10-28 18:44:22 -0400950 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800951 main.log.error( self.name + ": EOF exception found" )
952 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400953 main.cleanup()
954 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800955 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800956 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400957 main.cleanup()
958 main.exit()
959
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800961 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800962 Given the a string containing the json representation of the "roles"
963 cli command and a partial or whole device id, returns a json object
964 containing the roles output for the first device whose id contains
965 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400966
967 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800968 A dict of the role assignments for the given device or
969 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800970 """
Jon Hall983a1702014-10-28 18:44:22 -0400971 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return None
974 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 rawRoles = self.roles()
976 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800977 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800979 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400981 return device
982 return None
Jon Hallc6793552016-01-19 14:18:37 -0800983 except ( TypeError, ValueError ):
984 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800985 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400989 main.cleanup()
990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800992 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400993 main.cleanup()
994 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800995
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800997 """
Jon Hall94fd0472014-12-08 11:52:42 -0800998 Iterates through each device and checks if there is a master assigned
999 Returns: main.TRUE if each device has a master
1000 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001001 """
Jon Hall94fd0472014-12-08 11:52:42 -08001002 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 rawRoles = self.roles()
1004 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001005 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001007 # print device
1008 if device[ 'master' ] == "none":
1009 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001010 return main.FALSE
1011 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001012 except ( TypeError, ValueError ):
1013 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001014 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001015 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001018 main.cleanup()
1019 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001020 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001021 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001022 main.cleanup()
1023 main.exit()
1024
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001026 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 Returns string of paths, and the cost.
1028 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001029 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001030 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1032 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001033 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001034 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001035 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001036 main.log.error( "Error in getting paths" )
1037 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001038 else:
kelvin8ec71442015-01-15 16:57:00 -08001039 path = handle.split( ";" )[ 0 ]
1040 cost = handle.split( ";" )[ 1 ]
1041 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001042 except AssertionError:
1043 main.log.exception( "" )
1044 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001045 except TypeError:
1046 main.log.exception( self.name + ": Object not as expected" )
1047 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001051 main.cleanup()
1052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001054 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001055 main.cleanup()
1056 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001057
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001059 """
Jon Hallffb386d2014-11-21 13:43:38 -08001060 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001061 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001063 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001064 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001065 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 cmdStr += " -j"
1068 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001069 if handle:
1070 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001071 # TODO: Maybe make this less hardcoded
1072 # ConsistentMap Exceptions
1073 assert "org.onosproject.store.service" not in handle
1074 # Node not leader
1075 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001076 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001077 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001078 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001079 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001080 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001081 except TypeError:
1082 main.log.exception( self.name + ": Object not as expected" )
1083 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001084 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001085 main.log.error( self.name + ": EOF exception found" )
1086 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 main.cleanup()
1088 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001089 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001090 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001091 main.cleanup()
1092 main.exit()
1093
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001095 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001097
Jon Hallefbd9792015-03-05 16:11:36 -08001098 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001099 partial mac address
1100
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001102 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001103 try:
kelvin8ec71442015-01-15 16:57:00 -08001104 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 return None
1106 else:
1107 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 rawHosts = self.hosts()
1109 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001110 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001112 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001113 if not host:
1114 pass
1115 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001116 return host
1117 return None
Jon Hallc6793552016-01-19 14:18:37 -08001118 except ( TypeError, ValueError ):
1119 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001120 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001121 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001122 main.log.error( self.name + ": EOF exception found" )
1123 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001124 main.cleanup()
1125 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001126 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001127 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001128 main.cleanup()
1129 main.exit()
1130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001132 """
1133 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001135
andrewonlab3f0a4af2014-10-17 12:25:14 -04001136 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 IMPORTANT:
1139 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001140 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141 Furthermore, it assumes that value of VLAN is '-1'
1142 Description:
kelvin8ec71442015-01-15 16:57:00 -08001143 Converts mininet hosts ( h1, h2, h3... ) into
1144 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1145 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001150 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 hostHex = hex( int( host ) ).zfill( 12 )
1152 hostHex = str( hostHex ).replace( 'x', '0' )
1153 i = iter( str( hostHex ) )
1154 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1155 hostHex = hostHex + "/-1"
1156 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001159
Jon Halld4d4b372015-01-28 16:02:41 -08001160 except TypeError:
1161 main.log.exception( self.name + ": Object not as expected" )
1162 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001163 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001164 main.log.error( self.name + ": EOF exception found" )
1165 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001166 main.cleanup()
1167 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001168 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001169 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001170 main.cleanup()
1171 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001172
Jeremy Songsterc032f162016-08-04 17:14:49 -07001173 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001174 """
andrewonlabe6745342014-10-17 14:29:13 -04001175 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 * hostIdOne: ONOS host id for host1
1177 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 Optional:
1179 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001180 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001181 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001182 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001183 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001184 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 Returns:
1186 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001187 """
andrewonlabe6745342014-10-17 14:29:13 -04001188 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001189 cmdStr = "add-host-intent "
1190 if vlanId:
1191 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001192 if setVlan:
1193 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001194 if encap:
1195 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001196 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001198 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001199 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001200 if re.search( "Error", handle ):
1201 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001202 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001203 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001204 else:
1205 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001206 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1207 match = re.search('id=0x([\da-f]+),', handle)
1208 if match:
1209 return match.group()[3:-1]
1210 else:
1211 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001212 main.log.debug( "Response from ONOS was: " +
1213 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 return None
Jon Hallc6793552016-01-19 14:18:37 -08001215 except AssertionError:
1216 main.log.exception( "" )
1217 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001218 except TypeError:
1219 main.log.exception( self.name + ": Object not as expected" )
1220 return None
andrewonlabe6745342014-10-17 14:29:13 -04001221 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001222 main.log.error( self.name + ": EOF exception found" )
1223 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001224 main.cleanup()
1225 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001226 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001227 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001228 main.cleanup()
1229 main.exit()
1230
kelvin-onlabd3b64892015-01-20 13:26:24 -08001231 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001232 """
andrewonlab7b31d232014-10-24 13:31:47 -04001233 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 * ingressDevice: device id of ingress device
1235 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001236 Optional:
1237 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 Description:
1239 Adds an optical intent by specifying an ingress and egress device
1240 Returns:
1241 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001242 """
andrewonlab7b31d232014-10-24 13:31:47 -04001243 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1245 " " + str( egressDevice )
1246 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001247 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001248 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001249 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001250 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001251 main.log.error( "Error in adding Optical intent" )
1252 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001253 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001254 main.log.info( "Optical intent installed between " +
1255 str( ingressDevice ) + " and " +
1256 str( egressDevice ) )
1257 match = re.search('id=0x([\da-f]+),', handle)
1258 if match:
1259 return match.group()[3:-1]
1260 else:
1261 main.log.error( "Error, intent ID not found" )
1262 return None
Jon Hallc6793552016-01-19 14:18:37 -08001263 except AssertionError:
1264 main.log.exception( "" )
1265 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001266 except TypeError:
1267 main.log.exception( self.name + ": Object not as expected" )
1268 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001269 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001270 main.log.error( self.name + ": EOF exception found" )
1271 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001272 main.cleanup()
1273 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001274 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001275 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001276 main.cleanup()
1277 main.exit()
1278
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001280 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 ingressDevice,
1282 egressDevice,
1283 portIngress="",
1284 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001285 ethType="",
1286 ethSrc="",
1287 ethDst="",
1288 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001290 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001291 ipProto="",
1292 ipSrc="",
1293 ipDst="",
1294 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001295 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001296 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001297 setVlan="",
1298 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001299 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001300 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 * ingressDevice: device id of ingress device
1302 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001303 Optional:
1304 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001305 * ethSrc: specify ethSrc ( i.e. src mac addr )
1306 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001307 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001309 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001310 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001311 * ipSrc: specify ip source address
1312 * ipDst: specify ip destination address
1313 * tcpSrc: specify tcp source port
1314 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001315 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001316 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001317 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001318 Description:
kelvin8ec71442015-01-15 16:57:00 -08001319 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001320 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001321 Returns:
1322 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001323
Jon Halle3f39ff2015-01-13 11:50:53 -08001324 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001325 options developers provide for point-to-point
1326 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001327 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001328 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001329 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001330
Jeremy Songsterff553672016-05-12 17:06:23 -07001331 if ethType:
1332 cmd += " --ethType " + str( ethType )
1333 if ethSrc:
1334 cmd += " --ethSrc " + str( ethSrc )
1335 if ethDst:
1336 cmd += " --ethDst " + str( ethDst )
1337 if bandwidth:
1338 cmd += " --bandwidth " + str( bandwidth )
1339 if lambdaAlloc:
1340 cmd += " --lambda "
1341 if ipProto:
1342 cmd += " --ipProto " + str( ipProto )
1343 if ipSrc:
1344 cmd += " --ipSrc " + str( ipSrc )
1345 if ipDst:
1346 cmd += " --ipDst " + str( ipDst )
1347 if tcpSrc:
1348 cmd += " --tcpSrc " + str( tcpSrc )
1349 if tcpDst:
1350 cmd += " --tcpDst " + str( tcpDst )
1351 if vlanId:
1352 cmd += " -v " + str( vlanId )
1353 if setVlan:
1354 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001355 if encap:
1356 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001357 if protected:
1358 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001359
kelvin8ec71442015-01-15 16:57:00 -08001360 # Check whether the user appended the port
1361 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 if "/" in ingressDevice:
1363 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001364 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001366 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001367 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 # Would it make sense to throw an exception and exit
1369 # the test?
1370 return None
andrewonlab36af3822014-11-18 17:48:18 -05001371
kelvin8ec71442015-01-15 16:57:00 -08001372 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 str( ingressDevice ) + "/" +\
1374 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001375
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 if "/" in egressDevice:
1377 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001378 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 main.log.error( "You must specify the egress port" )
1381 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001382
kelvin8ec71442015-01-15 16:57:00 -08001383 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 str( egressDevice ) + "/" +\
1385 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001386
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001388 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001389 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001390 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001391 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001392 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001393 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001394 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001395 # TODO: print out all the options in this message?
1396 main.log.info( "Point-to-point intent installed between " +
1397 str( ingressDevice ) + " and " +
1398 str( egressDevice ) )
1399 match = re.search('id=0x([\da-f]+),', handle)
1400 if match:
1401 return match.group()[3:-1]
1402 else:
1403 main.log.error( "Error, intent ID not found" )
1404 return None
Jon Hallc6793552016-01-19 14:18:37 -08001405 except AssertionError:
1406 main.log.exception( "" )
1407 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001408 except TypeError:
1409 main.log.exception( self.name + ": Object not as expected" )
1410 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001411 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001412 main.log.error( self.name + ": EOF exception found" )
1413 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001414 main.cleanup()
1415 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001416 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001417 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001418 main.cleanup()
1419 main.exit()
1420
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001422 self,
shahshreyac2f97072015-03-19 17:04:29 -07001423 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001425 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001427 ethType="",
1428 ethSrc="",
1429 ethDst="",
1430 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001432 ipProto="",
1433 ipSrc="",
1434 ipDst="",
1435 tcpSrc="",
1436 tcpDst="",
1437 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001438 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001439 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001440 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001441 partial=False,
1442 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001443 """
shahshreyad0c80432014-12-04 16:56:05 -08001444 Note:
shahshreya70622b12015-03-19 17:19:00 -07001445 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001446 is same. That is, all ingress devices include port numbers
1447 with a "/" or all ingress devices could specify device
1448 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001449 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001450 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001451 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001453 Optional:
1454 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001455 * ethSrc: specify ethSrc ( i.e. src mac addr )
1456 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001457 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001459 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001460 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001461 * ipSrc: specify ip source address
1462 * ipDst: specify ip destination address
1463 * tcpSrc: specify tcp source port
1464 * tcpDst: specify tcp destination port
1465 * setEthSrc: action to Rewrite Source MAC Address
1466 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001467 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001468 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001469 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001470 Description:
kelvin8ec71442015-01-15 16:57:00 -08001471 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001472 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001473 Returns:
1474 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001475
Jon Halle3f39ff2015-01-13 11:50:53 -08001476 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001477 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001478 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001479 """
shahshreyad0c80432014-12-04 16:56:05 -08001480 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001481 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001482
Jeremy Songsterff553672016-05-12 17:06:23 -07001483 if ethType:
1484 cmd += " --ethType " + str( ethType )
1485 if ethSrc:
1486 cmd += " --ethSrc " + str( ethSrc )
1487 if ethDst:
1488 cmd += " --ethDst " + str( ethDst )
1489 if bandwidth:
1490 cmd += " --bandwidth " + str( bandwidth )
1491 if lambdaAlloc:
1492 cmd += " --lambda "
1493 if ipProto:
1494 cmd += " --ipProto " + str( ipProto )
1495 if ipSrc:
1496 cmd += " --ipSrc " + str( ipSrc )
1497 if ipDst:
1498 cmd += " --ipDst " + str( ipDst )
1499 if tcpSrc:
1500 cmd += " --tcpSrc " + str( tcpSrc )
1501 if tcpDst:
1502 cmd += " --tcpDst " + str( tcpDst )
1503 if setEthSrc:
1504 cmd += " --setEthSrc " + str( setEthSrc )
1505 if setEthDst:
1506 cmd += " --setEthDst " + str( setEthDst )
1507 if vlanId:
1508 cmd += " -v " + str( vlanId )
1509 if setVlan:
1510 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001511 if partial:
1512 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001513 if encap:
1514 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001515
kelvin8ec71442015-01-15 16:57:00 -08001516 # Check whether the user appended the port
1517 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001518
1519 if portIngressList is None:
1520 for ingressDevice in ingressDeviceList:
1521 if "/" in ingressDevice:
1522 cmd += " " + str( ingressDevice )
1523 else:
1524 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001525 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001526 # TODO: perhaps more meaningful return
1527 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001528 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001529 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001530 for ingressDevice, portIngress in zip( ingressDeviceList,
1531 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001532 cmd += " " + \
1533 str( ingressDevice ) + "/" +\
1534 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001535 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001536 main.log.error( "Device list and port list does not " +
1537 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001538 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 if "/" in egressDevice:
1540 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001541 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001542 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001543 main.log.error( "You must specify " +
1544 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001545 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001546
kelvin8ec71442015-01-15 16:57:00 -08001547 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 str( egressDevice ) + "/" +\
1549 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001550 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001551 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001552 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001553 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001554 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001555 main.log.error( "Error in adding multipoint-to-singlepoint " +
1556 "intent" )
1557 return None
shahshreyad0c80432014-12-04 16:56:05 -08001558 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001559 match = re.search('id=0x([\da-f]+),', handle)
1560 if match:
1561 return match.group()[3:-1]
1562 else:
1563 main.log.error( "Error, intent ID not found" )
1564 return None
Jon Hallc6793552016-01-19 14:18:37 -08001565 except AssertionError:
1566 main.log.exception( "" )
1567 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001568 except TypeError:
1569 main.log.exception( self.name + ": Object not as expected" )
1570 return None
1571 except pexpect.EOF:
1572 main.log.error( self.name + ": EOF exception found" )
1573 main.log.error( self.name + ": " + self.handle.before )
1574 main.cleanup()
1575 main.exit()
1576 except Exception:
1577 main.log.exception( self.name + ": Uncaught exception!" )
1578 main.cleanup()
1579 main.exit()
1580
1581 def addSinglepointToMultipointIntent(
1582 self,
1583 ingressDevice,
1584 egressDeviceList,
1585 portIngress="",
1586 portEgressList=None,
1587 ethType="",
1588 ethSrc="",
1589 ethDst="",
1590 bandwidth="",
1591 lambdaAlloc=False,
1592 ipProto="",
1593 ipSrc="",
1594 ipDst="",
1595 tcpSrc="",
1596 tcpDst="",
1597 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001598 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001599 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001600 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001601 partial=False,
1602 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001603 """
1604 Note:
1605 This function assumes the format of all egress devices
1606 is same. That is, all egress devices include port numbers
1607 with a "/" or all egress devices could specify device
1608 ids and port numbers seperately.
1609 Required:
1610 * EgressDeviceList: List of device ids of egress device
1611 ( Atleast 2 eress devices required in the list )
1612 * ingressDevice: device id of ingress device
1613 Optional:
1614 * ethType: specify ethType
1615 * ethSrc: specify ethSrc ( i.e. src mac addr )
1616 * ethDst: specify ethDst ( i.e. dst mac addr )
1617 * bandwidth: specify bandwidth capacity of link
1618 * lambdaAlloc: if True, intent will allocate lambda
1619 for the specified intent
1620 * ipProto: specify ip protocol
1621 * ipSrc: specify ip source address
1622 * ipDst: specify ip destination address
1623 * tcpSrc: specify tcp source port
1624 * tcpDst: specify tcp destination port
1625 * setEthSrc: action to Rewrite Source MAC Address
1626 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001627 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001628 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001629 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001630 Description:
1631 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1632 specifying device id's and optional fields
1633 Returns:
1634 A string of the intent id or None on error
1635
1636 NOTE: This function may change depending on the
1637 options developers provide for singlepoint-to-multipoint
1638 intent via cli
1639 """
1640 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001641 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001642
Jeremy Songsterff553672016-05-12 17:06:23 -07001643 if ethType:
1644 cmd += " --ethType " + str( ethType )
1645 if ethSrc:
1646 cmd += " --ethSrc " + str( ethSrc )
1647 if ethDst:
1648 cmd += " --ethDst " + str( ethDst )
1649 if bandwidth:
1650 cmd += " --bandwidth " + str( bandwidth )
1651 if lambdaAlloc:
1652 cmd += " --lambda "
1653 if ipProto:
1654 cmd += " --ipProto " + str( ipProto )
1655 if ipSrc:
1656 cmd += " --ipSrc " + str( ipSrc )
1657 if ipDst:
1658 cmd += " --ipDst " + str( ipDst )
1659 if tcpSrc:
1660 cmd += " --tcpSrc " + str( tcpSrc )
1661 if tcpDst:
1662 cmd += " --tcpDst " + str( tcpDst )
1663 if setEthSrc:
1664 cmd += " --setEthSrc " + str( setEthSrc )
1665 if setEthDst:
1666 cmd += " --setEthDst " + str( setEthDst )
1667 if vlanId:
1668 cmd += " -v " + str( vlanId )
1669 if setVlan:
1670 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001671 if partial:
1672 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001673 if encap:
1674 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001675
1676 # Check whether the user appended the port
1677 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001678
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 if "/" in ingressDevice:
1680 cmd += " " + str( ingressDevice )
1681 else:
1682 if not portIngress:
1683 main.log.error( "You must specify " +
1684 "the Ingress port" )
1685 return main.FALSE
1686
1687 cmd += " " +\
1688 str( ingressDevice ) + "/" +\
1689 str( portIngress )
1690
1691 if portEgressList is None:
1692 for egressDevice in egressDeviceList:
1693 if "/" in egressDevice:
1694 cmd += " " + str( egressDevice )
1695 else:
1696 main.log.error( "You must specify " +
1697 "the egress port" )
1698 # TODO: perhaps more meaningful return
1699 return main.FALSE
1700 else:
1701 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001702 for egressDevice, portEgress in zip( egressDeviceList,
1703 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001704 cmd += " " + \
1705 str( egressDevice ) + "/" +\
1706 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001707 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001708 main.log.error( "Device list and port list does not " +
1709 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001710 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001711 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001712 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001713 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001714 # If error, return error message
1715 if re.search( "Error", handle ):
1716 main.log.error( "Error in adding singlepoint-to-multipoint " +
1717 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001718 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001719 else:
1720 match = re.search('id=0x([\da-f]+),', handle)
1721 if match:
1722 return match.group()[3:-1]
1723 else:
1724 main.log.error( "Error, intent ID not found" )
1725 return None
Jon Hallc6793552016-01-19 14:18:37 -08001726 except AssertionError:
1727 main.log.exception( "" )
1728 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001729 except TypeError:
1730 main.log.exception( self.name + ": Object not as expected" )
1731 return None
shahshreyad0c80432014-12-04 16:56:05 -08001732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001733 main.log.error( self.name + ": EOF exception found" )
1734 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001735 main.cleanup()
1736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001737 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001738 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001739 main.cleanup()
1740 main.exit()
1741
Hari Krishna9e232602015-04-13 17:29:08 -07001742 def addMplsIntent(
1743 self,
1744 ingressDevice,
1745 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001746 ingressPort="",
1747 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001748 ethType="",
1749 ethSrc="",
1750 ethDst="",
1751 bandwidth="",
1752 lambdaAlloc=False,
1753 ipProto="",
1754 ipSrc="",
1755 ipDst="",
1756 tcpSrc="",
1757 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001758 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001759 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001760 priority=""):
1761 """
1762 Required:
1763 * ingressDevice: device id of ingress device
1764 * egressDevice: device id of egress device
1765 Optional:
1766 * ethType: specify ethType
1767 * ethSrc: specify ethSrc ( i.e. src mac addr )
1768 * ethDst: specify ethDst ( i.e. dst mac addr )
1769 * bandwidth: specify bandwidth capacity of link
1770 * lambdaAlloc: if True, intent will allocate lambda
1771 for the specified intent
1772 * ipProto: specify ip protocol
1773 * ipSrc: specify ip source address
1774 * ipDst: specify ip destination address
1775 * tcpSrc: specify tcp source port
1776 * tcpDst: specify tcp destination port
1777 * ingressLabel: Ingress MPLS label
1778 * egressLabel: Egress MPLS label
1779 Description:
1780 Adds MPLS intent by
1781 specifying device id's and optional fields
1782 Returns:
1783 A string of the intent id or None on error
1784
1785 NOTE: This function may change depending on the
1786 options developers provide for MPLS
1787 intent via cli
1788 """
1789 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001790 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001791
Jeremy Songsterff553672016-05-12 17:06:23 -07001792 if ethType:
1793 cmd += " --ethType " + str( ethType )
1794 if ethSrc:
1795 cmd += " --ethSrc " + str( ethSrc )
1796 if ethDst:
1797 cmd += " --ethDst " + str( ethDst )
1798 if bandwidth:
1799 cmd += " --bandwidth " + str( bandwidth )
1800 if lambdaAlloc:
1801 cmd += " --lambda "
1802 if ipProto:
1803 cmd += " --ipProto " + str( ipProto )
1804 if ipSrc:
1805 cmd += " --ipSrc " + str( ipSrc )
1806 if ipDst:
1807 cmd += " --ipDst " + str( ipDst )
1808 if tcpSrc:
1809 cmd += " --tcpSrc " + str( tcpSrc )
1810 if tcpDst:
1811 cmd += " --tcpDst " + str( tcpDst )
1812 if ingressLabel:
1813 cmd += " --ingressLabel " + str( ingressLabel )
1814 if egressLabel:
1815 cmd += " --egressLabel " + str( egressLabel )
1816 if priority:
1817 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001818
1819 # Check whether the user appended the port
1820 # or provided it as an input
1821 if "/" in ingressDevice:
1822 cmd += " " + str( ingressDevice )
1823 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001824 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001825 main.log.error( "You must specify the ingress port" )
1826 return None
1827
1828 cmd += " " + \
1829 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001830 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001831
1832 if "/" in egressDevice:
1833 cmd += " " + str( egressDevice )
1834 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001835 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001836 main.log.error( "You must specify the egress port" )
1837 return None
1838
1839 cmd += " " +\
1840 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001841 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001842
1843 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001844 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001845 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001846 # If error, return error message
1847 if re.search( "Error", handle ):
1848 main.log.error( "Error in adding mpls intent" )
1849 return None
1850 else:
1851 # TODO: print out all the options in this message?
1852 main.log.info( "MPLS intent installed between " +
1853 str( ingressDevice ) + " and " +
1854 str( egressDevice ) )
1855 match = re.search('id=0x([\da-f]+),', handle)
1856 if match:
1857 return match.group()[3:-1]
1858 else:
1859 main.log.error( "Error, intent ID not found" )
1860 return None
Jon Hallc6793552016-01-19 14:18:37 -08001861 except AssertionError:
1862 main.log.exception( "" )
1863 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001864 except TypeError:
1865 main.log.exception( self.name + ": Object not as expected" )
1866 return None
1867 except pexpect.EOF:
1868 main.log.error( self.name + ": EOF exception found" )
1869 main.log.error( self.name + ": " + self.handle.before )
1870 main.cleanup()
1871 main.exit()
1872 except Exception:
1873 main.log.exception( self.name + ": Uncaught exception!" )
1874 main.cleanup()
1875 main.exit()
1876
Jon Hallefbd9792015-03-05 16:11:36 -08001877 def removeIntent( self, intentId, app='org.onosproject.cli',
1878 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001879 """
shahshreya1c818fc2015-02-26 13:44:08 -08001880 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001881 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001882 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001883 -p or --purge: Purge the intent from the store after removal
1884
Jon Halle3f39ff2015-01-13 11:50:53 -08001885 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001886 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001887 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001888 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001889 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001890 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001891 if purge:
1892 cmdStr += " -p"
1893 if sync:
1894 cmdStr += " -s"
1895
1896 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001897 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001898 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001899 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001900 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001901 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001902 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001903 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001904 # TODO: Should this be main.TRUE
1905 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001906 except AssertionError:
1907 main.log.exception( "" )
1908 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001909 except TypeError:
1910 main.log.exception( self.name + ": Object not as expected" )
1911 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001915 main.cleanup()
1916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001918 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001919 main.cleanup()
1920 main.exit()
1921
YPZhangfebf7302016-05-24 16:45:56 -07001922 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001923 """
1924 Description:
1925 Remove all the intents
1926 Optional args:-
1927 -s or --sync: Waits for the removal before returning
1928 -p or --purge: Purge the intent from the store after removal
1929 Returns:
1930 Returns main.TRUE if all intents are removed, otherwise returns
1931 main.FALSE; Returns None for exception
1932 """
1933 try:
1934 cmdStr = "remove-intent"
1935 if purge:
1936 cmdStr += " -p"
1937 if sync:
1938 cmdStr += " -s"
1939
1940 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001941 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001942 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001943 assert "Command not found:" not in handle, handle
1944 if re.search( "Error", handle ):
1945 main.log.error( "Error in removing intent" )
1946 return main.FALSE
1947 else:
1948 return main.TRUE
1949 except AssertionError:
1950 main.log.exception( "" )
1951 return None
1952 except TypeError:
1953 main.log.exception( self.name + ": Object not as expected" )
1954 return None
1955 except pexpect.EOF:
1956 main.log.error( self.name + ": EOF exception found" )
1957 main.log.error( self.name + ": " + self.handle.before )
1958 main.cleanup()
1959 main.exit()
1960 except Exception:
1961 main.log.exception( self.name + ": Uncaught exception!" )
1962 main.cleanup()
1963 main.exit()
1964
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001965 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001966 """
1967 Purges all WITHDRAWN Intents
1968 """
1969 try:
1970 cmdStr = "purge-intents"
1971 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001972 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001973 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001974 if re.search( "Error", handle ):
1975 main.log.error( "Error in purging intents" )
1976 return main.FALSE
1977 else:
1978 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001979 except AssertionError:
1980 main.log.exception( "" )
1981 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001982 except TypeError:
1983 main.log.exception( self.name + ": Object not as expected" )
1984 return None
1985 except pexpect.EOF:
1986 main.log.error( self.name + ": EOF exception found" )
1987 main.log.error( self.name + ": " + self.handle.before )
1988 main.cleanup()
1989 main.exit()
1990 except Exception:
1991 main.log.exception( self.name + ": Uncaught exception!" )
1992 main.cleanup()
1993 main.exit()
1994
kelvin-onlabd3b64892015-01-20 13:26:24 -08001995 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001996 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001997 NOTE: This method should be used after installing application:
1998 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001999 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002000 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002001 Description:
2002 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002003 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002004 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002005 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002006 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002007 cmdStr += " -j"
2008 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002009 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002010 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002011 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002012 except AssertionError:
2013 main.log.exception( "" )
2014 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002015 except TypeError:
2016 main.log.exception( self.name + ": Object not as expected" )
2017 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002018 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002019 main.log.error( self.name + ": EOF exception found" )
2020 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002021 main.cleanup()
2022 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002023 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002024 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002025 main.cleanup()
2026 main.exit()
2027
pingping-lin54b03372015-08-13 14:43:10 -07002028 def ipv4RouteNumber( self ):
2029 """
2030 NOTE: This method should be used after installing application:
2031 onos-app-sdnip
2032 Description:
2033 Obtain the total IPv4 routes number in the system
2034 """
2035 try:
2036 cmdStr = "routes -s -j"
2037 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002038 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002039 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002040 jsonResult = json.loads( handle )
2041 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002042 except AssertionError:
2043 main.log.exception( "" )
2044 return None
2045 except ( TypeError, ValueError ):
2046 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002047 return None
2048 except pexpect.EOF:
2049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
2051 main.cleanup()
2052 main.exit()
2053 except Exception:
2054 main.log.exception( self.name + ": Uncaught exception!" )
2055 main.cleanup()
2056 main.exit()
2057
pingping-lin8244a3b2015-09-16 13:36:56 -07002058 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002059 """
andrewonlabe6745342014-10-17 14:29:13 -04002060 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002061 Obtain intents from the ONOS cli.
2062 Optional:
2063 * jsonFormat: Enable output formatting in json, default to True
2064 * summary: Whether only output the intent summary, defaults to False
2065 * type: Only output a certain type of intent. This options is valid
2066 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002067 """
andrewonlabe6745342014-10-17 14:29:13 -04002068 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002069 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002070 if summary:
2071 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002072 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002073 cmdStr += " -j"
2074 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002075 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002076 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002077 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002078 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002079 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002080 else:
Jon Hallff566d52016-01-15 14:45:36 -08002081 intentType = ""
2082 # IF we want the summary of a specific intent type
2083 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002084 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002085 if intentType in jsonResult.keys():
2086 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002087 else:
Jon Hallff566d52016-01-15 14:45:36 -08002088 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002089 return handle
2090 else:
2091 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002092 except AssertionError:
2093 main.log.exception( "" )
2094 return None
2095 except ( TypeError, ValueError ):
2096 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002097 return None
2098 except pexpect.EOF:
2099 main.log.error( self.name + ": EOF exception found" )
2100 main.log.error( self.name + ": " + self.handle.before )
2101 main.cleanup()
2102 main.exit()
2103 except Exception:
2104 main.log.exception( self.name + ": Uncaught exception!" )
2105 main.cleanup()
2106 main.exit()
2107
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 def getIntentState(self, intentsId, intentsJson=None):
2109 """
You Wangfdcbfc42016-05-16 12:16:53 -07002110 Description:
2111 Gets intent state. Accepts a single intent ID (string type) or a
2112 list of intent IDs.
2113 Parameters:
2114 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002115 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002116 Returns:
2117 Returns the state (string type) of the ID if a single intent ID is
2118 accepted.
2119 Returns a list of dictionaries if a list of intent IDs is accepted,
2120 and each dictionary maps 'id' to the Intent ID and 'state' to
2121 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002122 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002123 try:
2124 state = "State is Undefined"
2125 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002126 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002127 else:
Jon Hallc6793552016-01-19 14:18:37 -08002128 rawJson = intentsJson
2129 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002130 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002131 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002132 if intentsId == intent[ 'id' ]:
2133 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002134 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002135 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2136 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002137 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002138 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002139 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002141 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002142 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 if intentsId[ i ] == intents[ 'id' ]:
2144 stateDict[ 'state' ] = intents[ 'state' ]
2145 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002146 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002147 break
Jon Hallefbd9792015-03-05 16:11:36 -08002148 if len( intentsId ) != len( dictList ):
2149 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002150 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002151 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002152 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002153 return None
Jon Hallc6793552016-01-19 14:18:37 -08002154 except ( TypeError, ValueError ):
2155 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002156 return None
2157 except pexpect.EOF:
2158 main.log.error( self.name + ": EOF exception found" )
2159 main.log.error( self.name + ": " + self.handle.before )
2160 main.cleanup()
2161 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002162 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002163 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002164 main.cleanup()
2165 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002166
kelvin-onlabf512e942015-06-08 19:42:59 -07002167 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002168 """
2169 Description:
2170 Check intents state
2171 Required:
2172 intentsId - List of intents ID to be checked
2173 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002174 expectedState - Check the expected state(s) of each intents
2175 state in the list.
2176 *NOTE: You can pass in a list of expected state,
2177 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002178 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002179 Returns main.TRUE only if all intent are the same as expected states
2180 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002181 """
2182 try:
2183 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002184 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002185 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002186 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002187 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002188 "getting intents state" )
2189 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002190
2191 if isinstance( expectedState, types.StringType ):
2192 for intents in intentsDict:
2193 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002194 main.log.debug( self.name + " : Intent ID - " +
2195 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002196 " actual state = " +
2197 intents.get( 'state' )
2198 + " does not equal expected state = "
2199 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002200 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002201
2202 elif isinstance( expectedState, types.ListType ):
2203 for intents in intentsDict:
2204 if not any( state == intents.get( 'state' ) for state in
2205 expectedState ):
2206 main.log.debug( self.name + " : Intent ID - " +
2207 intents.get( 'id' ) +
2208 " actual state = " +
2209 intents.get( 'state' ) +
2210 " does not equal expected states = "
2211 + str( expectedState ) )
2212 returnValue = main.FALSE
2213
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002214 if returnValue == main.TRUE:
2215 main.log.info( self.name + ": All " +
2216 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002217 " intents are in " + str( expectedState ) +
2218 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002219 return returnValue
2220 except TypeError:
2221 main.log.exception( self.name + ": Object not as expected" )
2222 return None
2223 except pexpect.EOF:
2224 main.log.error( self.name + ": EOF exception found" )
2225 main.log.error( self.name + ": " + self.handle.before )
2226 main.cleanup()
2227 main.exit()
2228 except Exception:
2229 main.log.exception( self.name + ": Uncaught exception!" )
2230 main.cleanup()
2231 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002232
You Wang66518af2016-05-16 15:32:59 -07002233 def compareIntent( self, intentDict ):
2234 """
2235 Description:
2236 Compare the intent ids and states provided in the argument with all intents in ONOS
2237 Return:
2238 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2239 Arguments:
2240 intentDict: a dictionary which maps intent ids to intent states
2241 """
2242 try:
2243 intentsRaw = self.intents()
2244 intentsJson = json.loads( intentsRaw )
2245 intentDictONOS = {}
2246 for intent in intentsJson:
2247 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002248 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002249 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002250 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002251 str( len( intentDict ) ) + " expected and " +
2252 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002253 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002254 for intentID in intentDict.keys():
2255 if not intentID in intentDictONOS.keys():
2256 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2257 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002258 else:
2259 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2260 main.log.debug( self.name + ": intent ID - " + intentID +
2261 " expected state is " + intentDict[ intentID ] +
2262 " but actual state is " + intentDictONOS[ intentID ] )
2263 returnValue = main.FALSE
2264 intentDictONOS.pop( intentID )
2265 if len( intentDictONOS ) > 0:
2266 returnValue = main.FALSE
2267 for intentID in intentDictONOS.keys():
2268 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002269 if returnValue == main.TRUE:
2270 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2271 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002272 except KeyError:
2273 main.log.exception( self.name + ": KeyError exception found" )
2274 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002275 except ( TypeError, ValueError ):
2276 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002277 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002278 except pexpect.EOF:
2279 main.log.error( self.name + ": EOF exception found" )
2280 main.log.error( self.name + ": " + self.handle.before )
2281 main.cleanup()
2282 main.exit()
2283 except Exception:
2284 main.log.exception( self.name + ": Uncaught exception!" )
2285 main.cleanup()
2286 main.exit()
2287
YPZhang14a4aa92016-07-15 13:37:15 -07002288 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002289 """
2290 Description:
2291 Check the number of installed intents.
2292 Optional:
2293 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002294 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002295 Return:
2296 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2297 , otherwise, returns main.FALSE.
2298 """
2299
2300 try:
2301 cmd = "intents -s -j"
2302
2303 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002304 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002305 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002306 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002307 response = json.loads( response )
2308
2309 # get total and installed number, see if they are match
2310 allState = response.get( 'all' )
2311 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002312 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002313 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002314 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002315 return main.FALSE
2316
Jon Hallc6793552016-01-19 14:18:37 -08002317 except ( TypeError, ValueError ):
2318 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002319 return None
2320 except pexpect.EOF:
2321 main.log.error( self.name + ": EOF exception found" )
2322 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002323 if noExit:
2324 return main.FALSE
2325 else:
2326 main.cleanup()
2327 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002328 except Exception:
2329 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002330 if noExit:
2331 return main.FALSE
2332 else:
2333 main.cleanup()
2334 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002335 except pexpect.TIMEOUT:
2336 main.log.error( self.name + ": ONOS timeout" )
2337 return None
GlennRCed771242016-01-13 17:02:47 -08002338
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002339 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002340 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002341 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002342 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002343 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002344 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002345 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002346 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002347 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002348 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002349 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002350 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002351 if noCore:
2352 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002353 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002354 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002355 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002356 assert "Command not found:" not in handle, handle
2357 if re.search( "Error:", handle ):
2358 main.log.error( self.name + ": flows() response: " +
2359 str( handle ) )
2360 return handle
2361 except AssertionError:
2362 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002363 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002364 except TypeError:
2365 main.log.exception( self.name + ": Object not as expected" )
2366 return None
Jon Hallc6793552016-01-19 14:18:37 -08002367 except pexpect.TIMEOUT:
2368 main.log.error( self.name + ": ONOS timeout" )
2369 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002371 main.log.error( self.name + ": EOF exception found" )
2372 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002373 main.cleanup()
2374 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002375 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002376 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002377 main.cleanup()
2378 main.exit()
2379
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002380 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002381 count = self.getTotalFlowsNum( timeout=timeout )
2382 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002383 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002384
YPZhangebf9eb52016-05-12 15:20:24 -07002385 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002386 """
2387 Description:
GlennRCed771242016-01-13 17:02:47 -08002388 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002389 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2390 if the count of those states is 0, which means all current flows
2391 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002392 Optional:
GlennRCed771242016-01-13 17:02:47 -08002393 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002394 Return:
2395 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002396 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002397 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002398 """
2399 try:
GlennRCed771242016-01-13 17:02:47 -08002400 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2401 checkedStates = []
2402 statesCount = [0, 0, 0, 0]
2403 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002404 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002405 if rawFlows:
2406 # if we didn't get flows or flows function return None, we should return
2407 # main.Flase
2408 checkedStates.append( json.loads( rawFlows ) )
2409 else:
2410 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002411 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002412 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002413 try:
2414 statesCount[i] += int( c.get( "flowCount" ) )
2415 except TypeError:
2416 main.log.exception( "Json object not as expected" )
2417 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002418
GlennRCed771242016-01-13 17:02:47 -08002419 # We want to count PENDING_ADD if isPENDING is true
2420 if isPENDING:
2421 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2422 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002423 else:
GlennRCed771242016-01-13 17:02:47 -08002424 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2425 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002426 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002427 except ( TypeError, ValueError ):
2428 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002429 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002430
YPZhang240842b2016-05-17 12:00:50 -07002431 except AssertionError:
2432 main.log.exception( "" )
2433 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002434 except pexpect.EOF:
2435 main.log.error( self.name + ": EOF exception found" )
2436 main.log.error( self.name + ": " + self.handle.before )
2437 main.cleanup()
2438 main.exit()
2439 except Exception:
2440 main.log.exception( self.name + ": Uncaught exception!" )
2441 main.cleanup()
2442 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002443 except pexpect.TIMEOUT:
2444 main.log.error( self.name + ": ONOS timeout" )
2445 return None
2446
kelvin-onlab4df89f22015-04-13 18:10:23 -07002447
GlennRCed771242016-01-13 17:02:47 -08002448 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002449 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002450 """
andrewonlab87852b02014-11-19 18:44:19 -05002451 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002452 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002453 a specific point-to-point intent definition
2454 Required:
GlennRCed771242016-01-13 17:02:47 -08002455 * ingress: specify source dpid
2456 * egress: specify destination dpid
2457 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002458 Optional:
GlennRCed771242016-01-13 17:02:47 -08002459 * offset: the keyOffset is where the next batch of intents
2460 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002461 * noExit: If set to True, TestON will not exit if any error when issus command
2462 * getResponse: If set to True, function will return ONOS response.
2463
GlennRCed771242016-01-13 17:02:47 -08002464 Returns: If failed to push test intents, it will returen None,
2465 if successful, return true.
2466 Timeout expection will return None,
2467 TypeError will return false
2468 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002469 """
andrewonlab87852b02014-11-19 18:44:19 -05002470 try:
GlennRCed771242016-01-13 17:02:47 -08002471 if background:
2472 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002473 else:
GlennRCed771242016-01-13 17:02:47 -08002474 back = ""
2475 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002476 ingress,
2477 egress,
2478 batchSize,
2479 offset,
2480 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002481 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002482 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002483 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002484 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002485 if getResponse:
2486 return response
2487
GlennRCed771242016-01-13 17:02:47 -08002488 # TODO: We should handle if there is failure in installation
2489 return main.TRUE
2490
Jon Hallc6793552016-01-19 14:18:37 -08002491 except AssertionError:
2492 main.log.exception( "" )
2493 return None
GlennRCed771242016-01-13 17:02:47 -08002494 except pexpect.TIMEOUT:
2495 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002496 return None
andrewonlab87852b02014-11-19 18:44:19 -05002497 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002498 main.log.error( self.name + ": EOF exception found" )
2499 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002500 main.cleanup()
2501 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002502 except TypeError:
2503 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002504 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002505 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002506 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002507 main.cleanup()
2508 main.exit()
2509
YPZhangebf9eb52016-05-12 15:20:24 -07002510 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002511 """
2512 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002513 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002514 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002515 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002516 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002517 """
YPZhange3109a72016-02-02 11:25:37 -08002518
YPZhangb5d3f832016-01-23 22:54:26 -08002519 try:
YPZhange3109a72016-02-02 11:25:37 -08002520 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002521 cmd = "flows -c added"
2522 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2523 if rawFlows:
2524 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002525 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002526 for l in rawFlows:
2527 totalFlows += int(l.split("Count=")[1])
2528 else:
2529 main.log.error("Response not as expected!")
2530 return None
2531 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002532
You Wangd3cb2ce2016-05-16 14:01:24 -07002533 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002534 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002535 return None
2536 except pexpect.EOF:
2537 main.log.error( self.name + ": EOF exception found" )
2538 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002539 if not noExit:
2540 main.cleanup()
2541 main.exit()
2542 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002543 except Exception:
2544 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002545 if not noExit:
2546 main.cleanup()
2547 main.exit()
2548 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002549 except pexpect.TIMEOUT:
2550 main.log.error( self.name + ": ONOS timeout" )
2551 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002552
YPZhang14a4aa92016-07-15 13:37:15 -07002553 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002554 """
2555 Description:
2556 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002557 Optional:
2558 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002559 Return:
2560 The number of intents
2561 """
2562 try:
2563 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002564 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002565 if response == None:
2566 return -1
2567 response = json.loads( response )
2568 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002569 except ( TypeError, ValueError ):
2570 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002571 return None
2572 except pexpect.EOF:
2573 main.log.error( self.name + ": EOF exception found" )
2574 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002575 if noExit:
2576 return -1
2577 else:
2578 main.cleanup()
2579 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002580 except Exception:
2581 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002582 if noExit:
2583 return -1
2584 else:
2585 main.cleanup()
2586 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002587
kelvin-onlabd3b64892015-01-20 13:26:24 -08002588 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002589 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002590 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002591 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002592 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002593 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002594 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002595 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002596 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002597 cmdStr += " -j"
2598 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002599 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002600 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002601 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002602 except AssertionError:
2603 main.log.exception( "" )
2604 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002605 except TypeError:
2606 main.log.exception( self.name + ": Object not as expected" )
2607 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002611 main.cleanup()
2612 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002614 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002615 main.cleanup()
2616 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002617
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002619 """
2620 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002621 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002622 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002623 """
andrewonlab867212a2014-10-22 20:13:38 -04002624 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002625 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002626 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002627 cmdStr += " -j"
2628 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002630 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002631 if handle:
2632 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002633 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002634 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002635 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002636 else:
2637 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002638 except AssertionError:
2639 main.log.exception( "" )
2640 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002641 except TypeError:
2642 main.log.exception( self.name + ": Object not as expected" )
2643 return None
andrewonlab867212a2014-10-22 20:13:38 -04002644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002645 main.log.error( self.name + ": EOF exception found" )
2646 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002647 main.cleanup()
2648 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002649 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002650 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002651 main.cleanup()
2652 main.exit()
2653
kelvin8ec71442015-01-15 16:57:00 -08002654 # Wrapper functions ****************
2655 # Wrapper functions use existing driver
2656 # functions and extends their use case.
2657 # For example, we may use the output of
2658 # a normal driver function, and parse it
2659 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002660
kelvin-onlabd3b64892015-01-20 13:26:24 -08002661 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002662 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002663 Description:
2664 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002665 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002666 try:
kelvin8ec71442015-01-15 16:57:00 -08002667 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002668 intentsStr = self.intents(jsonFormat=True)
2669 # Convert to a dictionary
2670 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002671 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002672 for intent in intents:
2673 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002675 except TypeError:
2676 main.log.exception( self.name + ": Object not as expected" )
2677 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002679 main.log.error( self.name + ": EOF exception found" )
2680 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002681 main.cleanup()
2682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002683 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002684 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002685 main.cleanup()
2686 main.exit()
2687
You Wang3c276252016-09-21 15:21:36 -07002688 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002689 """
2690 Determine the number of flow rules for the given device id that are
2691 in the added state
You Wang3c276252016-09-21 15:21:36 -07002692 Params:
2693 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002694 """
2695 try:
You Wang3c276252016-09-21 15:21:36 -07002696 if core:
2697 cmdStr = "flows any " + str( deviceId ) + " | " +\
2698 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2699 else:
2700 cmdStr = "flows any " + str( deviceId ) + " | " +\
2701 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002702 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002703 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002704 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002705 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002706 except AssertionError:
2707 main.log.exception( "" )
2708 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002709 except pexpect.EOF:
2710 main.log.error( self.name + ": EOF exception found" )
2711 main.log.error( self.name + ": " + self.handle.before )
2712 main.cleanup()
2713 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002714 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002715 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002716 main.cleanup()
2717 main.exit()
2718
kelvin-onlabd3b64892015-01-20 13:26:24 -08002719 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002720 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002721 Use 'devices' function to obtain list of all devices
2722 and parse the result to obtain a list of all device
2723 id's. Returns this list. Returns empty list if no
2724 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002725 List is ordered sequentially
2726
andrewonlab3e15ead2014-10-15 14:21:34 -04002727 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002728 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002729 the ids. By obtaining the list of device ids on the fly,
2730 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002731 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002732 try:
kelvin8ec71442015-01-15 16:57:00 -08002733 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002734 devicesStr = self.devices( jsonFormat=False )
2735 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002736
kelvin-onlabd3b64892015-01-20 13:26:24 -08002737 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002738 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002739 return idList
kelvin8ec71442015-01-15 16:57:00 -08002740
2741 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002743 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002744 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002745 # Split list further into arguments before and after string
2746 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 # append to idList
2748 for arg in tempList:
2749 idList.append( arg.split( "id=" )[ 1 ] )
2750 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002751
Jon Halld4d4b372015-01-28 16:02:41 -08002752 except TypeError:
2753 main.log.exception( self.name + ": Object not as expected" )
2754 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002755 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002756 main.log.error( self.name + ": EOF exception found" )
2757 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002758 main.cleanup()
2759 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002761 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002762 main.cleanup()
2763 main.exit()
2764
kelvin-onlabd3b64892015-01-20 13:26:24 -08002765 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002766 """
andrewonlab7c211572014-10-15 16:45:20 -04002767 Uses 'nodes' function to obtain list of all nodes
2768 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002769 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002770 Returns:
2771 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002772 """
andrewonlab7c211572014-10-15 16:45:20 -04002773 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002774 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002776 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002777 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002779 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002780 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002781 nodesJson = json.loads( nodesStr )
2782 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002784 except ( TypeError, ValueError ):
2785 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002786 return None
andrewonlab7c211572014-10-15 16:45:20 -04002787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002788 main.log.error( self.name + ": EOF exception found" )
2789 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002790 main.cleanup()
2791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002793 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002794 main.cleanup()
2795 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002796
kelvin-onlabd3b64892015-01-20 13:26:24 -08002797 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002798 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002799 Return the first device from the devices api whose 'id' contains 'dpid'
2800 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002801 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002802 try:
kelvin8ec71442015-01-15 16:57:00 -08002803 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002804 return None
2805 else:
kelvin8ec71442015-01-15 16:57:00 -08002806 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002807 rawDevices = self.devices()
2808 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002809 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002810 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002811 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2812 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002813 return device
2814 return None
Jon Hallc6793552016-01-19 14:18:37 -08002815 except ( TypeError, ValueError ):
2816 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002817 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002818 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002819 main.log.error( self.name + ": EOF exception found" )
2820 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002821 main.cleanup()
2822 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002823 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002824 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002825 main.cleanup()
2826 main.exit()
2827
You Wang24139872016-05-03 11:48:47 -07002828 def getTopology( self, topologyOutput ):
2829 """
2830 Definition:
2831 Loads a json topology output
2832 Return:
2833 topology = current ONOS topology
2834 """
2835 import json
2836 try:
2837 # either onos:topology or 'topology' will work in CLI
2838 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002839 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002840 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002841 except ( TypeError, ValueError ):
2842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2843 return None
You Wang24139872016-05-03 11:48:47 -07002844 except pexpect.EOF:
2845 main.log.error( self.name + ": EOF exception found" )
2846 main.log.error( self.name + ": " + self.handle.before )
2847 main.cleanup()
2848 main.exit()
2849 except Exception:
2850 main.log.exception( self.name + ": Uncaught exception!" )
2851 main.cleanup()
2852 main.exit()
2853
Flavio Castro82ee2f62016-06-07 15:04:12 -07002854 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002855 """
Jon Hallefbd9792015-03-05 16:11:36 -08002856 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002857 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002858 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002859
Flavio Castro82ee2f62016-06-07 15:04:12 -07002860 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002861 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002862 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002863 logLevel = level to log to.
2864 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002865
Jon Hallefbd9792015-03-05 16:11:36 -08002866 Returns: main.TRUE if the number of switches and links are correct,
2867 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002868 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002869 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002870 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002871 try:
You Wang13310252016-07-31 10:56:14 -07002872 summary = self.summary()
2873 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002874 except ( TypeError, ValueError ):
2875 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2876 return main.ERROR
2877 try:
2878 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002879 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002880 return main.ERROR
2881 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002882 # Is the number of switches is what we expected
2883 devices = topology.get( 'devices', False )
2884 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002885 nodes = summary.get( 'nodes', False )
2886 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002887 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002889 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002890 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002891 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2892 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002893 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002894 output = output + "The number of links and switches match "\
2895 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002896 result = main.TRUE
2897 else:
You Wang24139872016-05-03 11:48:47 -07002898 output = output + \
2899 "The number of links and switches does not match " + \
2900 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002901 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002902 output = output + "\n ONOS sees %i devices" % int( devices )
2903 output = output + " (%i expected) " % int( numoswitch )
2904 output = output + "and %i links " % int( links )
2905 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002906 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002907 output = output + "and %i controllers " % int( nodes )
2908 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002910 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002911 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002912 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002913 else:
You Wang24139872016-05-03 11:48:47 -07002914 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002915 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002916 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002917 main.log.error( self.name + ": EOF exception found" )
2918 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002919 main.cleanup()
2920 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002922 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002923 main.cleanup()
2924 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002925
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002927 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002928 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 deviceId must be the id of a device as seen in the onos devices command
2930 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002931 role must be either master, standby, or none
2932
Jon Halle3f39ff2015-01-13 11:50:53 -08002933 Returns:
2934 main.TRUE or main.FALSE based on argument verification and
2935 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002937 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002938 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002939 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002940 cmdStr = "device-role " +\
2941 str( deviceId ) + " " +\
2942 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002943 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002944 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002945 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002946 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002947 if re.search( "Error", handle ):
2948 # end color output to escape any colours
2949 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002950 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002951 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002952 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002953 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002954 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002955 main.log.error( "Invalid 'role' given to device_role(). " +
2956 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002957 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002958 except AssertionError:
2959 main.log.exception( "" )
2960 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002961 except TypeError:
2962 main.log.exception( self.name + ": Object not as expected" )
2963 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002964 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002965 main.log.error( self.name + ": EOF exception found" )
2966 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002967 main.cleanup()
2968 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002969 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002970 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002971 main.cleanup()
2972 main.exit()
2973
kelvin-onlabd3b64892015-01-20 13:26:24 -08002974 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002975 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002976 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002977 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002978 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002979 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002980 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002981 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002983 cmdStr += " -j"
2984 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002985 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002986 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002987 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002988 except AssertionError:
2989 main.log.exception( "" )
2990 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002991 except TypeError:
2992 main.log.exception( self.name + ": Object not as expected" )
2993 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002995 main.log.error( self.name + ": EOF exception found" )
2996 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002997 main.cleanup()
2998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003000 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003001 main.cleanup()
3002 main.exit()
3003
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003006 CLI command to get the current leader for the Election test application
3007 NOTE: Requires installation of the onos-app-election feature
3008 Returns: Node IP of the leader if one exists
3009 None if none exists
3010 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003011 """
Jon Hall94fd0472014-12-08 11:52:42 -08003012 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003013 cmdStr = "election-test-leader"
3014 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003015 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003016 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003017 # Leader
3018 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003019 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003020 nodeSearch = re.search( leaderPattern, response )
3021 if nodeSearch:
3022 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003023 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003024 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003025 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003026 # no leader
3027 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003028 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003029 nullSearch = re.search( nullPattern, response )
3030 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003031 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003033 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003034 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003035 main.log.error( "Error in electionTestLeader on " + self.name +
3036 ": " + "unexpected response" )
3037 main.log.error( repr( response ) )
3038 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003039 except AssertionError:
3040 main.log.exception( "" )
3041 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003042 except TypeError:
3043 main.log.exception( self.name + ": Object not as expected" )
3044 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003045 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003046 main.log.error( self.name + ": EOF exception found" )
3047 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003048 main.cleanup()
3049 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003050 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003051 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003052 main.cleanup()
3053 main.exit()
3054
kelvin-onlabd3b64892015-01-20 13:26:24 -08003055 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003056 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003057 CLI command to run for leadership of the Election test application.
3058 NOTE: Requires installation of the onos-app-election feature
3059 Returns: Main.TRUE on success
3060 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003061 """
Jon Hall94fd0472014-12-08 11:52:42 -08003062 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003063 cmdStr = "election-test-run"
3064 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003065 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003066 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003067 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003068 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003069 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003070 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003071 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003072 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003074 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003075 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003076 main.log.error( "Error in electionTestRun on " + self.name +
3077 ": " + "unexpected response" )
3078 main.log.error( repr( response ) )
3079 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003080 except AssertionError:
3081 main.log.exception( "" )
3082 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003083 except TypeError:
3084 main.log.exception( self.name + ": Object not as expected" )
3085 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003087 main.log.error( self.name + ": EOF exception found" )
3088 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003089 main.cleanup()
3090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003091 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003092 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003093 main.cleanup()
3094 main.exit()
3095
kelvin-onlabd3b64892015-01-20 13:26:24 -08003096 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003097 """
Jon Hall94fd0472014-12-08 11:52:42 -08003098 * CLI command to withdraw the local node from leadership election for
3099 * the Election test application.
3100 #NOTE: Requires installation of the onos-app-election feature
3101 Returns: Main.TRUE on success
3102 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003103 """
Jon Hall94fd0472014-12-08 11:52:42 -08003104 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003105 cmdStr = "election-test-withdraw"
3106 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003107 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003108 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003109 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003110 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003111 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003112 if re.search( successPattern, response ):
3113 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003114 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003115 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003116 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003117 main.log.error( "Error in electionTestWithdraw on " +
3118 self.name + ": " + "unexpected response" )
3119 main.log.error( repr( response ) )
3120 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003121 except AssertionError:
3122 main.log.exception( "" )
3123 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003124 except TypeError:
3125 main.log.exception( self.name + ": Object not as expected" )
3126 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003128 main.log.error( self.name + ": EOF exception found" )
3129 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003130 main.cleanup()
3131 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003133 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003134 main.cleanup()
3135 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003136
kelvin8ec71442015-01-15 16:57:00 -08003137 def getDevicePortsEnabledCount( self, dpid ):
3138 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003143 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3144 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003145 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003146 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003147 if re.search( "No such device", output ):
3148 main.log.error( "Error in getting ports" )
3149 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003150 return output
Jon Hallc6793552016-01-19 14:18:37 -08003151 except AssertionError:
3152 main.log.exception( "" )
3153 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003154 except TypeError:
3155 main.log.exception( self.name + ": Object not as expected" )
3156 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003157 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003158 main.log.error( self.name + ": EOF exception found" )
3159 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003160 main.cleanup()
3161 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003162 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003163 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164 main.cleanup()
3165 main.exit()
3166
kelvin8ec71442015-01-15 16:57:00 -08003167 def getDeviceLinksActiveCount( self, dpid ):
3168 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003169 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003170 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003171 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003172 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3174 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003175 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003176 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003177 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003178 main.log.error( "Error in getting ports " )
3179 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003180 return output
Jon Hallc6793552016-01-19 14:18:37 -08003181 except AssertionError:
3182 main.log.exception( "" )
3183 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003184 except TypeError:
3185 main.log.exception( self.name + ": Object not as expected" )
3186 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003188 main.log.error( self.name + ": EOF exception found" )
3189 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003190 main.cleanup()
3191 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003192 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003193 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003194 main.cleanup()
3195 main.exit()
3196
kelvin8ec71442015-01-15 16:57:00 -08003197 def getAllIntentIds( self ):
3198 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003199 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003200 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003201 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003202 cmdStr = "onos:intents | grep id="
3203 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003204 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003205 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003206 if re.search( "Error", output ):
3207 main.log.error( "Error in getting ports" )
3208 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003209 return output
Jon Hallc6793552016-01-19 14:18:37 -08003210 except AssertionError:
3211 main.log.exception( "" )
3212 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003213 except TypeError:
3214 main.log.exception( self.name + ": Object not as expected" )
3215 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003216 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003217 main.log.error( self.name + ": EOF exception found" )
3218 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003219 main.cleanup()
3220 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003221 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003222 main.log.exception( self.name + ": Uncaught exception!" )
3223 main.cleanup()
3224 main.exit()
3225
Jon Hall73509952015-02-24 16:42:56 -08003226 def intentSummary( self ):
3227 """
Jon Hallefbd9792015-03-05 16:11:36 -08003228 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003229 """
3230 try:
3231 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003232 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003233 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003234 states.append( intent.get( 'state', None ) )
3235 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003236 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003237 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003238 except ( TypeError, ValueError ):
3239 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003240 return None
3241 except pexpect.EOF:
3242 main.log.error( self.name + ": EOF exception found" )
3243 main.log.error( self.name + ": " + self.handle.before )
3244 main.cleanup()
3245 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003246 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003247 main.log.exception( self.name + ": Uncaught exception!" )
3248 main.cleanup()
3249 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003250
Jon Hall61282e32015-03-19 11:34:11 -07003251 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003252 """
3253 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003254 Optional argument:
3255 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003256 """
Jon Hall63604932015-02-26 17:09:50 -08003257 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003258 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003259 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003260 cmdStr += " -j"
3261 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003262 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003263 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003264 return output
Jon Hallc6793552016-01-19 14:18:37 -08003265 except AssertionError:
3266 main.log.exception( "" )
3267 return None
Jon Hall63604932015-02-26 17:09:50 -08003268 except TypeError:
3269 main.log.exception( self.name + ": Object not as expected" )
3270 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003271 except pexpect.EOF:
3272 main.log.error( self.name + ": EOF exception found" )
3273 main.log.error( self.name + ": " + self.handle.before )
3274 main.cleanup()
3275 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003276 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003277 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003278 main.cleanup()
3279 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003280
acsmarsa4a4d1e2015-07-10 16:01:24 -07003281 def leaderCandidates( self, jsonFormat=True ):
3282 """
3283 Returns the output of the leaders -c command.
3284 Optional argument:
3285 * jsonFormat - boolean indicating if you want output in json
3286 """
3287 try:
3288 cmdStr = "onos:leaders -c"
3289 if jsonFormat:
3290 cmdStr += " -j"
3291 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003292 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003293 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003294 return output
Jon Hallc6793552016-01-19 14:18:37 -08003295 except AssertionError:
3296 main.log.exception( "" )
3297 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298 except TypeError:
3299 main.log.exception( self.name + ": Object not as expected" )
3300 return None
3301 except pexpect.EOF:
3302 main.log.error( self.name + ": EOF exception found" )
3303 main.log.error( self.name + ": " + self.handle.before )
3304 main.cleanup()
3305 main.exit()
3306 except Exception:
3307 main.log.exception( self.name + ": Uncaught exception!" )
3308 main.cleanup()
3309 main.exit()
3310
Jon Hallc6793552016-01-19 14:18:37 -08003311 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003312 """
3313 Returns a list in format [leader,candidate1,candidate2,...] for a given
3314 topic parameter and an empty list if the topic doesn't exist
3315 If no leader is elected leader in the returned list will be "none"
3316 Returns None if there is a type error processing the json object
3317 """
3318 try:
Jon Hall6e709752016-02-01 13:38:46 -08003319 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003320 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003321 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003322 assert "Command not found:" not in rawOutput, rawOutput
3323 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003324 results = []
3325 for dict in output:
3326 if dict["topic"] == topic:
3327 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003328 candidates = re.split( ", ", dict["candidates"][1:-1] )
3329 results.append( leader )
3330 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003331 return results
Jon Hallc6793552016-01-19 14:18:37 -08003332 except AssertionError:
3333 main.log.exception( "" )
3334 return None
3335 except ( TypeError, ValueError ):
3336 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003337 return None
3338 except pexpect.EOF:
3339 main.log.error( self.name + ": EOF exception found" )
3340 main.log.error( self.name + ": " + self.handle.before )
3341 main.cleanup()
3342 main.exit()
3343 except Exception:
3344 main.log.exception( self.name + ": Uncaught exception!" )
3345 main.cleanup()
3346 main.exit()
3347
Jon Hall61282e32015-03-19 11:34:11 -07003348 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003349 """
3350 Returns the output of the intent Pending map.
3351 """
Jon Hall63604932015-02-26 17:09:50 -08003352 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003353 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003354 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003355 cmdStr += " -j"
3356 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003357 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003358 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003359 return output
Jon Hallc6793552016-01-19 14:18:37 -08003360 except AssertionError:
3361 main.log.exception( "" )
3362 return None
Jon Hall63604932015-02-26 17:09:50 -08003363 except TypeError:
3364 main.log.exception( self.name + ": Object not as expected" )
3365 return None
3366 except pexpect.EOF:
3367 main.log.error( self.name + ": EOF exception found" )
3368 main.log.error( self.name + ": " + self.handle.before )
3369 main.cleanup()
3370 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003371 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003372 main.log.exception( self.name + ": Uncaught exception!" )
3373 main.cleanup()
3374 main.exit()
3375
Jon Hall2c8959e2016-12-16 12:17:34 -08003376 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003377 """
3378 Returns the output of the raft partitions command for ONOS.
3379 """
Jon Hall61282e32015-03-19 11:34:11 -07003380 # Sample JSON
3381 # {
3382 # "leader": "tcp://10.128.30.11:7238",
3383 # "members": [
3384 # "tcp://10.128.30.11:7238",
3385 # "tcp://10.128.30.17:7238",
3386 # "tcp://10.128.30.13:7238",
3387 # ],
3388 # "name": "p1",
3389 # "term": 3
3390 # },
Jon Hall63604932015-02-26 17:09:50 -08003391 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003392 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003393 if candidates:
3394 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003395 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003396 cmdStr += " -j"
3397 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003398 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003399 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003400 return output
Jon Hallc6793552016-01-19 14:18:37 -08003401 except AssertionError:
3402 main.log.exception( "" )
3403 return None
Jon Hall63604932015-02-26 17:09:50 -08003404 except TypeError:
3405 main.log.exception( self.name + ": Object not as expected" )
3406 return None
3407 except pexpect.EOF:
3408 main.log.error( self.name + ": EOF exception found" )
3409 main.log.error( self.name + ": " + self.handle.before )
3410 main.cleanup()
3411 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003412 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003413 main.log.exception( self.name + ": Uncaught exception!" )
3414 main.cleanup()
3415 main.exit()
3416
Jon Halle9f909e2016-09-23 10:43:12 -07003417 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003418 """
3419 Returns the output of the apps command for ONOS. This command lists
3420 information about installed ONOS applications
3421 """
3422 # Sample JSON object
3423 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3424 # "description":"ONOS OpenFlow protocol southbound providers",
3425 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3426 # "features":"[onos-openflow]","state":"ACTIVE"}]
3427 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003428 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003429 if summary:
3430 cmdStr += " -s"
3431 if active:
3432 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003433 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003434 cmdStr += " -j"
3435 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003436 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003437 assert "Command not found:" not in output, output
3438 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003439 return output
Jon Hallbe379602015-03-24 13:39:32 -07003440 # FIXME: look at specific exceptions/Errors
3441 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003442 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003443 return None
3444 except TypeError:
3445 main.log.exception( self.name + ": Object not as expected" )
3446 return None
3447 except pexpect.EOF:
3448 main.log.error( self.name + ": EOF exception found" )
3449 main.log.error( self.name + ": " + self.handle.before )
3450 main.cleanup()
3451 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003452 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003453 main.log.exception( self.name + ": Uncaught exception!" )
3454 main.cleanup()
3455 main.exit()
3456
Jon Hall146f1522015-03-24 15:33:24 -07003457 def appStatus( self, appName ):
3458 """
3459 Uses the onos:apps cli command to return the status of an application.
3460 Returns:
3461 "ACTIVE" - If app is installed and activated
3462 "INSTALLED" - If app is installed and deactivated
3463 "UNINSTALLED" - If app is not installed
3464 None - on error
3465 """
Jon Hall146f1522015-03-24 15:33:24 -07003466 try:
3467 if not isinstance( appName, types.StringType ):
3468 main.log.error( self.name + ".appStatus(): appName must be" +
3469 " a string" )
3470 return None
3471 output = self.apps( jsonFormat=True )
3472 appsJson = json.loads( output )
3473 state = None
3474 for app in appsJson:
3475 if appName == app.get('name'):
3476 state = app.get('state')
3477 break
3478 if state == "ACTIVE" or state == "INSTALLED":
3479 return state
3480 elif state is None:
3481 return "UNINSTALLED"
3482 elif state:
3483 main.log.error( "Unexpected state from 'onos:apps': " +
3484 str( state ) )
3485 return state
Jon Hallc6793552016-01-19 14:18:37 -08003486 except ( TypeError, ValueError ):
3487 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003488 return None
3489 except pexpect.EOF:
3490 main.log.error( self.name + ": EOF exception found" )
3491 main.log.error( self.name + ": " + self.handle.before )
3492 main.cleanup()
3493 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003494 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003495 main.log.exception( self.name + ": Uncaught exception!" )
3496 main.cleanup()
3497 main.exit()
3498
Jon Hallbe379602015-03-24 13:39:32 -07003499 def app( self, appName, option ):
3500 """
3501 Interacts with the app command for ONOS. This command manages
3502 application inventory.
3503 """
Jon Hallbe379602015-03-24 13:39:32 -07003504 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003505 # Validate argument types
3506 valid = True
3507 if not isinstance( appName, types.StringType ):
3508 main.log.error( self.name + ".app(): appName must be a " +
3509 "string" )
3510 valid = False
3511 if not isinstance( option, types.StringType ):
3512 main.log.error( self.name + ".app(): option must be a string" )
3513 valid = False
3514 if not valid:
3515 return main.FALSE
3516 # Validate Option
3517 option = option.lower()
3518 # NOTE: Install may become a valid option
3519 if option == "activate":
3520 pass
3521 elif option == "deactivate":
3522 pass
3523 elif option == "uninstall":
3524 pass
3525 else:
3526 # Invalid option
3527 main.log.error( "The ONOS app command argument only takes " +
3528 "the values: (activate|deactivate|uninstall)" +
3529 "; was given '" + option + "'")
3530 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003531 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003532 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003533 assert output is not None, "Error in sendline"
3534 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003535 if "Error executing command" in output:
3536 main.log.error( "Error in processing onos:app command: " +
3537 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003538 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003539 elif "No such application" in output:
3540 main.log.error( "The application '" + appName +
3541 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003542 return main.FALSE
3543 elif "Command not found:" in output:
3544 main.log.error( "Error in processing onos:app command: " +
3545 str( output ) )
3546 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003547 elif "Unsupported command:" in output:
3548 main.log.error( "Incorrect command given to 'app': " +
3549 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003550 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003551 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003552 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003553 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003554 except AssertionError:
3555 main.log.exception( self.name + ": AssertionError exception found" )
3556 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003557 except TypeError:
3558 main.log.exception( self.name + ": Object not as expected" )
3559 return main.ERROR
3560 except pexpect.EOF:
3561 main.log.error( self.name + ": EOF exception found" )
3562 main.log.error( self.name + ": " + self.handle.before )
3563 main.cleanup()
3564 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003565 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003566 main.log.exception( self.name + ": Uncaught exception!" )
3567 main.cleanup()
3568 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003569
Jon Hallbd16b922015-03-26 17:53:15 -07003570 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003571 """
3572 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003573 appName is the hierarchical app name, not the feature name
3574 If check is True, method will check the status of the app after the
3575 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003576 Returns main.TRUE if the command was successfully sent
3577 main.FALSE if the cli responded with an error or given
3578 incorrect input
3579 """
3580 try:
3581 if not isinstance( appName, types.StringType ):
3582 main.log.error( self.name + ".activateApp(): appName must be" +
3583 " a string" )
3584 return main.FALSE
3585 status = self.appStatus( appName )
3586 if status == "INSTALLED":
3587 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003588 if check and response == main.TRUE:
3589 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003590 status = self.appStatus( appName )
3591 if status == "ACTIVE":
3592 return main.TRUE
3593 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003594 main.log.debug( "The state of application " +
3595 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003596 time.sleep( 1 )
3597 return main.FALSE
3598 else: # not 'check' or command didn't succeed
3599 return response
Jon Hall146f1522015-03-24 15:33:24 -07003600 elif status == "ACTIVE":
3601 return main.TRUE
3602 elif status == "UNINSTALLED":
3603 main.log.error( self.name + ": Tried to activate the " +
3604 "application '" + appName + "' which is not " +
3605 "installed." )
3606 else:
3607 main.log.error( "Unexpected return value from appStatus: " +
3608 str( status ) )
3609 return main.ERROR
3610 except TypeError:
3611 main.log.exception( self.name + ": Object not as expected" )
3612 return main.ERROR
3613 except pexpect.EOF:
3614 main.log.error( self.name + ": EOF exception found" )
3615 main.log.error( self.name + ": " + self.handle.before )
3616 main.cleanup()
3617 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003618 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003619 main.log.exception( self.name + ": Uncaught exception!" )
3620 main.cleanup()
3621 main.exit()
3622
Jon Hallbd16b922015-03-26 17:53:15 -07003623 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003624 """
3625 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003626 appName is the hierarchical app name, not the feature name
3627 If check is True, method will check the status of the app after the
3628 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003629 Returns main.TRUE if the command was successfully sent
3630 main.FALSE if the cli responded with an error or given
3631 incorrect input
3632 """
3633 try:
3634 if not isinstance( appName, types.StringType ):
3635 main.log.error( self.name + ".deactivateApp(): appName must " +
3636 "be a string" )
3637 return main.FALSE
3638 status = self.appStatus( appName )
3639 if status == "INSTALLED":
3640 return main.TRUE
3641 elif status == "ACTIVE":
3642 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003643 if check and response == main.TRUE:
3644 for i in range(10): # try 10 times then give up
3645 status = self.appStatus( appName )
3646 if status == "INSTALLED":
3647 return main.TRUE
3648 else:
3649 time.sleep( 1 )
3650 return main.FALSE
3651 else: # not check or command didn't succeed
3652 return response
Jon Hall146f1522015-03-24 15:33:24 -07003653 elif status == "UNINSTALLED":
3654 main.log.warn( self.name + ": Tried to deactivate the " +
3655 "application '" + appName + "' which is not " +
3656 "installed." )
3657 return main.TRUE
3658 else:
3659 main.log.error( "Unexpected return value from appStatus: " +
3660 str( status ) )
3661 return main.ERROR
3662 except TypeError:
3663 main.log.exception( self.name + ": Object not as expected" )
3664 return main.ERROR
3665 except pexpect.EOF:
3666 main.log.error( self.name + ": EOF exception found" )
3667 main.log.error( self.name + ": " + self.handle.before )
3668 main.cleanup()
3669 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003670 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003671 main.log.exception( self.name + ": Uncaught exception!" )
3672 main.cleanup()
3673 main.exit()
3674
Jon Hallbd16b922015-03-26 17:53:15 -07003675 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003676 """
3677 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003678 appName is the hierarchical app name, not the feature name
3679 If check is True, method will check the status of the app after the
3680 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003681 Returns main.TRUE if the command was successfully sent
3682 main.FALSE if the cli responded with an error or given
3683 incorrect input
3684 """
3685 # TODO: check with Thomas about the state machine for apps
3686 try:
3687 if not isinstance( appName, types.StringType ):
3688 main.log.error( self.name + ".uninstallApp(): appName must " +
3689 "be a string" )
3690 return main.FALSE
3691 status = self.appStatus( appName )
3692 if status == "INSTALLED":
3693 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003694 if check and response == main.TRUE:
3695 for i in range(10): # try 10 times then give up
3696 status = self.appStatus( appName )
3697 if status == "UNINSTALLED":
3698 return main.TRUE
3699 else:
3700 time.sleep( 1 )
3701 return main.FALSE
3702 else: # not check or command didn't succeed
3703 return response
Jon Hall146f1522015-03-24 15:33:24 -07003704 elif status == "ACTIVE":
3705 main.log.warn( self.name + ": Tried to uninstall the " +
3706 "application '" + appName + "' which is " +
3707 "currently active." )
3708 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003709 if check and response == main.TRUE:
3710 for i in range(10): # try 10 times then give up
3711 status = self.appStatus( appName )
3712 if status == "UNINSTALLED":
3713 return main.TRUE
3714 else:
3715 time.sleep( 1 )
3716 return main.FALSE
3717 else: # not check or command didn't succeed
3718 return response
Jon Hall146f1522015-03-24 15:33:24 -07003719 elif status == "UNINSTALLED":
3720 return main.TRUE
3721 else:
3722 main.log.error( "Unexpected return value from appStatus: " +
3723 str( status ) )
3724 return main.ERROR
3725 except TypeError:
3726 main.log.exception( self.name + ": Object not as expected" )
3727 return main.ERROR
3728 except pexpect.EOF:
3729 main.log.error( self.name + ": EOF exception found" )
3730 main.log.error( self.name + ": " + self.handle.before )
3731 main.cleanup()
3732 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003733 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003734 main.log.exception( self.name + ": Uncaught exception!" )
3735 main.cleanup()
3736 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003737
3738 def appIDs( self, jsonFormat=True ):
3739 """
3740 Show the mappings between app id and app names given by the 'app-ids'
3741 cli command
3742 """
3743 try:
3744 cmdStr = "app-ids"
3745 if jsonFormat:
3746 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003747 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003748 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003749 assert "Command not found:" not in output, output
3750 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003751 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003752 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003753 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003754 return None
3755 except TypeError:
3756 main.log.exception( self.name + ": Object not as expected" )
3757 return None
3758 except pexpect.EOF:
3759 main.log.error( self.name + ": EOF exception found" )
3760 main.log.error( self.name + ": " + self.handle.before )
3761 main.cleanup()
3762 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003763 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003764 main.log.exception( self.name + ": Uncaught exception!" )
3765 main.cleanup()
3766 main.exit()
3767
3768 def appToIDCheck( self ):
3769 """
3770 This method will check that each application's ID listed in 'apps' is
3771 the same as the ID listed in 'app-ids'. The check will also check that
3772 there are no duplicate IDs issued. Note that an app ID should be
3773 a globaly unique numerical identifier for app/app-like features. Once
3774 an ID is registered, the ID is never freed up so that if an app is
3775 reinstalled it will have the same ID.
3776
3777 Returns: main.TRUE if the check passes and
3778 main.FALSE if the check fails or
3779 main.ERROR if there is some error in processing the test
3780 """
3781 try:
Jon Hall390696c2015-05-05 17:13:41 -07003782 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003783 rawJson = self.appIDs( jsonFormat=True )
3784 if rawJson:
3785 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003786 else:
Jon Hallc6793552016-01-19 14:18:37 -08003787 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003788 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003789 rawJson = self.apps( jsonFormat=True )
3790 if rawJson:
3791 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003792 else:
Jon Hallc6793552016-01-19 14:18:37 -08003793 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003794 bail = True
3795 if bail:
3796 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003797 result = main.TRUE
3798 for app in apps:
3799 appID = app.get( 'id' )
3800 if appID is None:
3801 main.log.error( "Error parsing app: " + str( app ) )
3802 result = main.FALSE
3803 appName = app.get( 'name' )
3804 if appName is None:
3805 main.log.error( "Error parsing app: " + str( app ) )
3806 result = main.FALSE
3807 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003808 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003809 # main.log.debug( "Comparing " + str( app ) + " to " +
3810 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003811 if not current: # if ids doesn't have this id
3812 result = main.FALSE
3813 main.log.error( "'app-ids' does not have the ID for " +
3814 str( appName ) + " that apps does." )
3815 elif len( current ) > 1:
3816 # there is more than one app with this ID
3817 result = main.FALSE
3818 # We will log this later in the method
3819 elif not current[0][ 'name' ] == appName:
3820 currentName = current[0][ 'name' ]
3821 result = main.FALSE
3822 main.log.error( "'app-ids' has " + str( currentName ) +
3823 " registered under id:" + str( appID ) +
3824 " but 'apps' has " + str( appName ) )
3825 else:
3826 pass # id and name match!
3827 # now make sure that app-ids has no duplicates
3828 idsList = []
3829 namesList = []
3830 for item in ids:
3831 idsList.append( item[ 'id' ] )
3832 namesList.append( item[ 'name' ] )
3833 if len( idsList ) != len( set( idsList ) ) or\
3834 len( namesList ) != len( set( namesList ) ):
3835 main.log.error( "'app-ids' has some duplicate entries: \n"
3836 + json.dumps( ids,
3837 sort_keys=True,
3838 indent=4,
3839 separators=( ',', ': ' ) ) )
3840 result = main.FALSE
3841 return result
Jon Hallc6793552016-01-19 14:18:37 -08003842 except ( TypeError, ValueError ):
3843 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003844 return main.ERROR
3845 except pexpect.EOF:
3846 main.log.error( self.name + ": EOF exception found" )
3847 main.log.error( self.name + ": " + self.handle.before )
3848 main.cleanup()
3849 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003850 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003851 main.log.exception( self.name + ": Uncaught exception!" )
3852 main.cleanup()
3853 main.exit()
3854
Jon Hallfb760a02015-04-13 15:35:03 -07003855 def getCfg( self, component=None, propName=None, short=False,
3856 jsonFormat=True ):
3857 """
3858 Get configuration settings from onos cli
3859 Optional arguments:
3860 component - Optionally only list configurations for a specific
3861 component. If None, all components with configurations
3862 are displayed. Case Sensitive string.
3863 propName - If component is specified, propName option will show
3864 only this specific configuration from that component.
3865 Case Sensitive string.
3866 jsonFormat - Returns output as json. Note that this will override
3867 the short option
3868 short - Short, less verbose, version of configurations.
3869 This is overridden by the json option
3870 returns:
3871 Output from cli as a string or None on error
3872 """
3873 try:
3874 baseStr = "cfg"
3875 cmdStr = " get"
3876 componentStr = ""
3877 if component:
3878 componentStr += " " + component
3879 if propName:
3880 componentStr += " " + propName
3881 if jsonFormat:
3882 baseStr += " -j"
3883 elif short:
3884 baseStr += " -s"
3885 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003886 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003887 assert "Command not found:" not in output, output
3888 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003889 return output
3890 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003891 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003892 return None
3893 except TypeError:
3894 main.log.exception( self.name + ": Object not as expected" )
3895 return None
3896 except pexpect.EOF:
3897 main.log.error( self.name + ": EOF exception found" )
3898 main.log.error( self.name + ": " + self.handle.before )
3899 main.cleanup()
3900 main.exit()
3901 except Exception:
3902 main.log.exception( self.name + ": Uncaught exception!" )
3903 main.cleanup()
3904 main.exit()
3905
3906 def setCfg( self, component, propName, value=None, check=True ):
3907 """
3908 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003909 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003910 component - The case sensitive name of the component whose
3911 property is to be set
3912 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003913 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003914 value - The value to set the property to. If None, will unset the
3915 property and revert it to it's default value(if applicable)
3916 check - Boolean, Check whether the option was successfully set this
3917 only applies when a value is given.
3918 returns:
3919 main.TRUE on success or main.FALSE on failure. If check is False,
3920 will return main.TRUE unless there is an error
3921 """
3922 try:
3923 baseStr = "cfg"
3924 cmdStr = " set " + str( component ) + " " + str( propName )
3925 if value is not None:
3926 cmdStr += " " + str( value )
3927 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003928 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003929 assert "Command not found:" not in output, output
3930 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003931 if value and check:
3932 results = self.getCfg( component=str( component ),
3933 propName=str( propName ),
3934 jsonFormat=True )
3935 # Check if current value is what we just set
3936 try:
3937 jsonOutput = json.loads( results )
3938 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003939 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003940 main.log.exception( "Error parsing cfg output" )
3941 main.log.error( "output:" + repr( results ) )
3942 return main.FALSE
3943 if current == str( value ):
3944 return main.TRUE
3945 return main.FALSE
3946 return main.TRUE
3947 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003948 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003949 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003950 except ( TypeError, ValueError ):
3951 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003952 return main.FALSE
3953 except pexpect.EOF:
3954 main.log.error( self.name + ": EOF exception found" )
3955 main.log.error( self.name + ": " + self.handle.before )
3956 main.cleanup()
3957 main.exit()
3958 except Exception:
3959 main.log.exception( self.name + ": Uncaught exception!" )
3960 main.cleanup()
3961 main.exit()
3962
Jon Hall390696c2015-05-05 17:13:41 -07003963 def setTestAdd( self, setName, values ):
3964 """
3965 CLI command to add elements to a distributed set.
3966 Arguments:
3967 setName - The name of the set to add to.
3968 values - The value(s) to add to the set, space seperated.
3969 Example usages:
3970 setTestAdd( "set1", "a b c" )
3971 setTestAdd( "set2", "1" )
3972 returns:
3973 main.TRUE on success OR
3974 main.FALSE if elements were already in the set OR
3975 main.ERROR on error
3976 """
3977 try:
3978 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3979 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003980 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003981 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003982 try:
3983 # TODO: Maybe make this less hardcoded
3984 # ConsistentMap Exceptions
3985 assert "org.onosproject.store.service" not in output
3986 # Node not leader
3987 assert "java.lang.IllegalStateException" not in output
3988 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003989 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003990 "command: " + str( output ) )
3991 retryTime = 30 # Conservative time, given by Madan
3992 main.log.info( "Waiting " + str( retryTime ) +
3993 "seconds before retrying." )
3994 time.sleep( retryTime ) # Due to change in mastership
3995 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003996 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003997 assert "Error executing command" not in output
3998 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3999 negativeMatch = "\[(.*)\] was already in set " + str( setName )
4000 main.log.info( self.name + ": " + output )
4001 if re.search( positiveMatch, output):
4002 return main.TRUE
4003 elif re.search( negativeMatch, output):
4004 return main.FALSE
4005 else:
4006 main.log.error( self.name + ": setTestAdd did not" +
4007 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004008 main.log.debug( self.name + " actual: " + repr( output ) )
4009 return main.ERROR
4010 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004011 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07004012 return main.ERROR
4013 except TypeError:
4014 main.log.exception( self.name + ": Object not as expected" )
4015 return main.ERROR
4016 except pexpect.EOF:
4017 main.log.error( self.name + ": EOF exception found" )
4018 main.log.error( self.name + ": " + self.handle.before )
4019 main.cleanup()
4020 main.exit()
4021 except Exception:
4022 main.log.exception( self.name + ": Uncaught exception!" )
4023 main.cleanup()
4024 main.exit()
4025
4026 def setTestRemove( self, setName, values, clear=False, retain=False ):
4027 """
4028 CLI command to remove elements from a distributed set.
4029 Required arguments:
4030 setName - The name of the set to remove from.
4031 values - The value(s) to remove from the set, space seperated.
4032 Optional arguments:
4033 clear - Clear all elements from the set
4034 retain - Retain only the given values. (intersection of the
4035 original set and the given set)
4036 returns:
4037 main.TRUE on success OR
4038 main.FALSE if the set was not changed OR
4039 main.ERROR on error
4040 """
4041 try:
4042 cmdStr = "set-test-remove "
4043 if clear:
4044 cmdStr += "-c " + str( setName )
4045 elif retain:
4046 cmdStr += "-r " + str( setName ) + " " + str( values )
4047 else:
4048 cmdStr += str( setName ) + " " + str( values )
4049 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004050 try:
Jon Halla495f562016-05-16 18:03:26 -07004051 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004052 # TODO: Maybe make this less hardcoded
4053 # ConsistentMap Exceptions
4054 assert "org.onosproject.store.service" not in output
4055 # Node not leader
4056 assert "java.lang.IllegalStateException" not in output
4057 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004058 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004059 "command: " + str( output ) )
4060 retryTime = 30 # Conservative time, given by Madan
4061 main.log.info( "Waiting " + str( retryTime ) +
4062 "seconds before retrying." )
4063 time.sleep( retryTime ) # Due to change in mastership
4064 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004065 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004066 assert "Command not found:" not in output, output
4067 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004068 main.log.info( self.name + ": " + output )
4069 if clear:
4070 pattern = "Set " + str( setName ) + " cleared"
4071 if re.search( pattern, output ):
4072 return main.TRUE
4073 elif retain:
4074 positivePattern = str( setName ) + " was pruned to contain " +\
4075 "only elements of set \[(.*)\]"
4076 negativePattern = str( setName ) + " was not changed by " +\
4077 "retaining only elements of the set " +\
4078 "\[(.*)\]"
4079 if re.search( positivePattern, output ):
4080 return main.TRUE
4081 elif re.search( negativePattern, output ):
4082 return main.FALSE
4083 else:
4084 positivePattern = "\[(.*)\] was removed from the set " +\
4085 str( setName )
4086 if ( len( values.split() ) == 1 ):
4087 negativePattern = "\[(.*)\] was not in set " +\
4088 str( setName )
4089 else:
4090 negativePattern = "No element of \[(.*)\] was in set " +\
4091 str( setName )
4092 if re.search( positivePattern, output ):
4093 return main.TRUE
4094 elif re.search( negativePattern, output ):
4095 return main.FALSE
4096 main.log.error( self.name + ": setTestRemove did not" +
4097 " match expected output" )
4098 main.log.debug( self.name + " expected: " + pattern )
4099 main.log.debug( self.name + " actual: " + repr( output ) )
4100 return main.ERROR
4101 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004102 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004103 return main.ERROR
4104 except TypeError:
4105 main.log.exception( self.name + ": Object not as expected" )
4106 return main.ERROR
4107 except pexpect.EOF:
4108 main.log.error( self.name + ": EOF exception found" )
4109 main.log.error( self.name + ": " + self.handle.before )
4110 main.cleanup()
4111 main.exit()
4112 except Exception:
4113 main.log.exception( self.name + ": Uncaught exception!" )
4114 main.cleanup()
4115 main.exit()
4116
4117 def setTestGet( self, setName, values="" ):
4118 """
4119 CLI command to get the elements in a distributed set.
4120 Required arguments:
4121 setName - The name of the set to remove from.
4122 Optional arguments:
4123 values - The value(s) to check if in the set, space seperated.
4124 returns:
4125 main.ERROR on error OR
4126 A list of elements in the set if no optional arguments are
4127 supplied OR
4128 A tuple containing the list then:
4129 main.FALSE if the given values are not in the set OR
4130 main.TRUE if the given values are in the set OR
4131 """
4132 try:
4133 values = str( values ).strip()
4134 setName = str( setName ).strip()
4135 length = len( values.split() )
4136 containsCheck = None
4137 # Patterns to match
4138 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004139 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004140 containsTrue = "Set " + setName + " contains the value " + values
4141 containsFalse = "Set " + setName + " did not contain the value " +\
4142 values
4143 containsAllTrue = "Set " + setName + " contains the the subset " +\
4144 setPattern
4145 containsAllFalse = "Set " + setName + " did not contain the the" +\
4146 " subset " + setPattern
4147
4148 cmdStr = "set-test-get "
4149 cmdStr += setName + " " + values
4150 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004151 try:
Jon Halla495f562016-05-16 18:03:26 -07004152 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004153 # TODO: Maybe make this less hardcoded
4154 # ConsistentMap Exceptions
4155 assert "org.onosproject.store.service" not in output
4156 # Node not leader
4157 assert "java.lang.IllegalStateException" not in output
4158 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004159 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004160 "command: " + str( output ) )
4161 retryTime = 30 # Conservative time, given by Madan
4162 main.log.info( "Waiting " + str( retryTime ) +
4163 "seconds before retrying." )
4164 time.sleep( retryTime ) # Due to change in mastership
4165 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004166 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004167 assert "Command not found:" not in output, output
4168 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004169 main.log.info( self.name + ": " + output )
4170
4171 if length == 0:
4172 match = re.search( pattern, output )
4173 else: # if given values
4174 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004175 patternTrue = pattern + "\r\n" + containsTrue
4176 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004177 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004178 patternTrue = pattern + "\r\n" + containsAllTrue
4179 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004180 matchTrue = re.search( patternTrue, output )
4181 matchFalse = re.search( patternFalse, output )
4182 if matchTrue:
4183 containsCheck = main.TRUE
4184 match = matchTrue
4185 elif matchFalse:
4186 containsCheck = main.FALSE
4187 match = matchFalse
4188 else:
4189 main.log.error( self.name + " setTestGet did not match " +\
4190 "expected output" )
4191 main.log.debug( self.name + " expected: " + pattern )
4192 main.log.debug( self.name + " actual: " + repr( output ) )
4193 match = None
4194 if match:
4195 setMatch = match.group( 1 )
4196 if setMatch == '':
4197 setList = []
4198 else:
4199 setList = setMatch.split( ", " )
4200 if length > 0:
4201 return ( setList, containsCheck )
4202 else:
4203 return setList
4204 else: # no match
4205 main.log.error( self.name + ": setTestGet did not" +
4206 " match expected output" )
4207 main.log.debug( self.name + " expected: " + pattern )
4208 main.log.debug( self.name + " actual: " + repr( output ) )
4209 return main.ERROR
4210 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004211 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004212 return main.ERROR
4213 except TypeError:
4214 main.log.exception( self.name + ": Object not as expected" )
4215 return main.ERROR
4216 except pexpect.EOF:
4217 main.log.error( self.name + ": EOF exception found" )
4218 main.log.error( self.name + ": " + self.handle.before )
4219 main.cleanup()
4220 main.exit()
4221 except Exception:
4222 main.log.exception( self.name + ": Uncaught exception!" )
4223 main.cleanup()
4224 main.exit()
4225
4226 def setTestSize( self, setName ):
4227 """
4228 CLI command to get the elements in a distributed set.
4229 Required arguments:
4230 setName - The name of the set to remove from.
4231 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004232 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004233 None on error
4234 """
4235 try:
4236 # TODO: Should this check against the number of elements returned
4237 # and then return true/false based on that?
4238 setName = str( setName ).strip()
4239 # Patterns to match
4240 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004241 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004242 setPattern
4243 cmdStr = "set-test-get -s "
4244 cmdStr += setName
4245 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004246 try:
Jon Halla495f562016-05-16 18:03:26 -07004247 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004248 # TODO: Maybe make this less hardcoded
4249 # ConsistentMap Exceptions
4250 assert "org.onosproject.store.service" not in output
4251 # Node not leader
4252 assert "java.lang.IllegalStateException" not in output
4253 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004254 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004255 "command: " + str( output ) )
4256 retryTime = 30 # Conservative time, given by Madan
4257 main.log.info( "Waiting " + str( retryTime ) +
4258 "seconds before retrying." )
4259 time.sleep( retryTime ) # Due to change in mastership
4260 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004261 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004262 assert "Command not found:" not in output, output
4263 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004264 main.log.info( self.name + ": " + output )
4265 match = re.search( pattern, output )
4266 if match:
4267 setSize = int( match.group( 1 ) )
4268 setMatch = match.group( 2 )
4269 if len( setMatch.split() ) == setSize:
4270 main.log.info( "The size returned by " + self.name +
4271 " matches the number of elements in " +
4272 "the returned set" )
4273 else:
4274 main.log.error( "The size returned by " + self.name +
4275 " does not match the number of " +
4276 "elements in the returned set." )
4277 return setSize
4278 else: # no match
4279 main.log.error( self.name + ": setTestGet did not" +
4280 " match expected output" )
4281 main.log.debug( self.name + " expected: " + pattern )
4282 main.log.debug( self.name + " actual: " + repr( output ) )
4283 return None
4284 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004285 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004286 return None
Jon Hall390696c2015-05-05 17:13:41 -07004287 except TypeError:
4288 main.log.exception( self.name + ": Object not as expected" )
4289 return None
4290 except pexpect.EOF:
4291 main.log.error( self.name + ": EOF exception found" )
4292 main.log.error( self.name + ": " + self.handle.before )
4293 main.cleanup()
4294 main.exit()
4295 except Exception:
4296 main.log.exception( self.name + ": Uncaught exception!" )
4297 main.cleanup()
4298 main.exit()
4299
Jon Hall80daded2015-05-27 16:07:00 -07004300 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004301 """
4302 Command to list the various counters in the system.
4303 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004304 if jsonFormat, a string of the json object returned by the cli
4305 command
4306 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004307 None on error
4308 """
Jon Hall390696c2015-05-05 17:13:41 -07004309 try:
4310 counters = {}
4311 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004312 if jsonFormat:
4313 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004314 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004315 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004316 assert "Command not found:" not in output, output
4317 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004318 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004319 return output
Jon Hall390696c2015-05-05 17:13:41 -07004320 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004321 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004322 return None
Jon Hall390696c2015-05-05 17:13:41 -07004323 except TypeError:
4324 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004325 return None
Jon Hall390696c2015-05-05 17:13:41 -07004326 except pexpect.EOF:
4327 main.log.error( self.name + ": EOF exception found" )
4328 main.log.error( self.name + ": " + self.handle.before )
4329 main.cleanup()
4330 main.exit()
4331 except Exception:
4332 main.log.exception( self.name + ": Uncaught exception!" )
4333 main.cleanup()
4334 main.exit()
4335
Jon Hall935db192016-04-19 00:22:04 -07004336 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004337 """
Jon Halle1a3b752015-07-22 13:02:46 -07004338 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004339 Required arguments:
4340 counter - The name of the counter to increment.
4341 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004342 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004343 returns:
4344 integer value of the counter or
4345 None on Error
4346 """
4347 try:
4348 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004349 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004350 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004351 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004352 if delta != 1:
4353 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004354 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004355 try:
Jon Halla495f562016-05-16 18:03:26 -07004356 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004357 # TODO: Maybe make this less hardcoded
4358 # ConsistentMap Exceptions
4359 assert "org.onosproject.store.service" not in output
4360 # Node not leader
4361 assert "java.lang.IllegalStateException" not in output
4362 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004363 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004364 "command: " + str( output ) )
4365 retryTime = 30 # Conservative time, given by Madan
4366 main.log.info( "Waiting " + str( retryTime ) +
4367 "seconds before retrying." )
4368 time.sleep( retryTime ) # Due to change in mastership
4369 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004370 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004371 assert "Command not found:" not in output, output
4372 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004373 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004374 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004375 match = re.search( pattern, output )
4376 if match:
4377 return int( match.group( 1 ) )
4378 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004379 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004380 " match expected output." )
4381 main.log.debug( self.name + " expected: " + pattern )
4382 main.log.debug( self.name + " actual: " + repr( output ) )
4383 return None
4384 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004385 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004386 return None
4387 except TypeError:
4388 main.log.exception( self.name + ": Object not as expected" )
4389 return None
4390 except pexpect.EOF:
4391 main.log.error( self.name + ": EOF exception found" )
4392 main.log.error( self.name + ": " + self.handle.before )
4393 main.cleanup()
4394 main.exit()
4395 except Exception:
4396 main.log.exception( self.name + ": Uncaught exception!" )
4397 main.cleanup()
4398 main.exit()
4399
Jon Hall935db192016-04-19 00:22:04 -07004400 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004401 """
4402 CLI command to get a distributed counter then add a delta to it.
4403 Required arguments:
4404 counter - The name of the counter to increment.
4405 Optional arguments:
4406 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004407 returns:
4408 integer value of the counter or
4409 None on Error
4410 """
4411 try:
4412 counter = str( counter )
4413 delta = int( delta )
4414 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004415 cmdStr += counter
4416 if delta != 1:
4417 cmdStr += " " + str( delta )
4418 output = self.sendline( cmdStr )
4419 try:
Jon Halla495f562016-05-16 18:03:26 -07004420 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004421 # TODO: Maybe make this less hardcoded
4422 # ConsistentMap Exceptions
4423 assert "org.onosproject.store.service" not in output
4424 # Node not leader
4425 assert "java.lang.IllegalStateException" not in output
4426 except AssertionError:
4427 main.log.error( "Error in processing '" + cmdStr + "' " +
4428 "command: " + str( output ) )
4429 retryTime = 30 # Conservative time, given by Madan
4430 main.log.info( "Waiting " + str( retryTime ) +
4431 "seconds before retrying." )
4432 time.sleep( retryTime ) # Due to change in mastership
4433 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004434 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004435 assert "Command not found:" not in output, output
4436 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004437 main.log.info( self.name + ": " + output )
4438 pattern = counter + " was updated to (-?\d+)"
4439 match = re.search( pattern, output )
4440 if match:
4441 return int( match.group( 1 ) )
4442 else:
4443 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4444 " match expected output." )
4445 main.log.debug( self.name + " expected: " + pattern )
4446 main.log.debug( self.name + " actual: " + repr( output ) )
4447 return None
4448 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004449 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004450 return None
4451 except TypeError:
4452 main.log.exception( self.name + ": Object not as expected" )
4453 return None
4454 except pexpect.EOF:
4455 main.log.error( self.name + ": EOF exception found" )
4456 main.log.error( self.name + ": " + self.handle.before )
4457 main.cleanup()
4458 main.exit()
4459 except Exception:
4460 main.log.exception( self.name + ": Uncaught exception!" )
4461 main.cleanup()
4462 main.exit()
4463
YPZhangfebf7302016-05-24 16:45:56 -07004464 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004465 """
4466 Description: Execute summary command in onos
4467 Returns: json object ( summary -j ), returns main.FALSE if there is
4468 no output
4469
4470 """
4471 try:
4472 cmdStr = "summary"
4473 if jsonFormat:
4474 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004475 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004476 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004477 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004478 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004479 if not handle:
4480 main.log.error( self.name + ": There is no output in " +
4481 "summary command" )
4482 return main.FALSE
4483 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004484 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004485 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004486 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004487 except TypeError:
4488 main.log.exception( self.name + ": Object not as expected" )
4489 return None
4490 except pexpect.EOF:
4491 main.log.error( self.name + ": EOF exception found" )
4492 main.log.error( self.name + ": " + self.handle.before )
4493 main.cleanup()
4494 main.exit()
4495 except Exception:
4496 main.log.exception( self.name + ": Uncaught exception!" )
4497 main.cleanup()
4498 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004499
Jon Hall935db192016-04-19 00:22:04 -07004500 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004501 """
4502 CLI command to get the value of a key in a consistent map using
4503 transactions. This a test function and can only get keys from the
4504 test map hard coded into the cli command
4505 Required arguments:
4506 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004507 returns:
4508 The string value of the key or
4509 None on Error
4510 """
4511 try:
4512 keyName = str( keyName )
4513 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004514 cmdStr += keyName
4515 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004516 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004517 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004518 try:
4519 # TODO: Maybe make this less hardcoded
4520 # ConsistentMap Exceptions
4521 assert "org.onosproject.store.service" not in output
4522 # Node not leader
4523 assert "java.lang.IllegalStateException" not in output
4524 except AssertionError:
4525 main.log.error( "Error in processing '" + cmdStr + "' " +
4526 "command: " + str( output ) )
4527 return None
4528 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4529 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004530 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004531 return None
4532 else:
4533 match = re.search( pattern, output )
4534 if match:
4535 return match.groupdict()[ 'value' ]
4536 else:
4537 main.log.error( self.name + ": transactionlMapGet did not" +
4538 " match expected output." )
4539 main.log.debug( self.name + " expected: " + pattern )
4540 main.log.debug( self.name + " actual: " + repr( output ) )
4541 return None
Jon Hallc6793552016-01-19 14:18:37 -08004542 except AssertionError:
4543 main.log.exception( "" )
4544 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004545 except TypeError:
4546 main.log.exception( self.name + ": Object not as expected" )
4547 return None
4548 except pexpect.EOF:
4549 main.log.error( self.name + ": EOF exception found" )
4550 main.log.error( self.name + ": " + self.handle.before )
4551 main.cleanup()
4552 main.exit()
4553 except Exception:
4554 main.log.exception( self.name + ": Uncaught exception!" )
4555 main.cleanup()
4556 main.exit()
4557
Jon Hall935db192016-04-19 00:22:04 -07004558 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004559 """
4560 CLI command to put a value into 'numKeys' number of keys in a
4561 consistent map using transactions. This a test function and can only
4562 put into keys named 'Key#' of the test map hard coded into the cli command
4563 Required arguments:
4564 numKeys - Number of keys to add the value to
4565 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004566 returns:
4567 A dictionary whose keys are the name of the keys put into the map
4568 and the values of the keys are dictionaries whose key-values are
4569 'value': value put into map and optionaly
4570 'oldValue': Previous value in the key or
4571 None on Error
4572
4573 Example output
4574 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4575 'Key2': {'value': 'Testing'} }
4576 """
4577 try:
4578 numKeys = str( numKeys )
4579 value = str( value )
4580 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004581 cmdStr += numKeys + " " + value
4582 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004583 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004584 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004585 try:
4586 # TODO: Maybe make this less hardcoded
4587 # ConsistentMap Exceptions
4588 assert "org.onosproject.store.service" not in output
4589 # Node not leader
4590 assert "java.lang.IllegalStateException" not in output
4591 except AssertionError:
4592 main.log.error( "Error in processing '" + cmdStr + "' " +
4593 "command: " + str( output ) )
4594 return None
4595 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4596 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4597 results = {}
4598 for line in output.splitlines():
4599 new = re.search( newPattern, line )
4600 updated = re.search( updatedPattern, line )
4601 if new:
4602 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4603 elif updated:
4604 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004605 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004606 else:
4607 main.log.error( self.name + ": transactionlMapGet did not" +
4608 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004609 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4610 newPattern,
4611 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004612 main.log.debug( self.name + " actual: " + repr( output ) )
4613 return results
Jon Hallc6793552016-01-19 14:18:37 -08004614 except AssertionError:
4615 main.log.exception( "" )
4616 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004617 except TypeError:
4618 main.log.exception( self.name + ": Object not as expected" )
4619 return None
4620 except pexpect.EOF:
4621 main.log.error( self.name + ": EOF exception found" )
4622 main.log.error( self.name + ": " + self.handle.before )
4623 main.cleanup()
4624 main.exit()
4625 except Exception:
4626 main.log.exception( self.name + ": Uncaught exception!" )
4627 main.cleanup()
4628 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004629
acsmarsdaea66c2015-09-03 11:44:06 -07004630 def maps( self, jsonFormat=True ):
4631 """
4632 Description: Returns result of onos:maps
4633 Optional:
4634 * jsonFormat: enable json formatting of output
4635 """
4636 try:
4637 cmdStr = "maps"
4638 if jsonFormat:
4639 cmdStr += " -j"
4640 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004641 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004642 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004643 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004644 except AssertionError:
4645 main.log.exception( "" )
4646 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004647 except TypeError:
4648 main.log.exception( self.name + ": Object not as expected" )
4649 return None
4650 except pexpect.EOF:
4651 main.log.error( self.name + ": EOF exception found" )
4652 main.log.error( self.name + ": " + self.handle.before )
4653 main.cleanup()
4654 main.exit()
4655 except Exception:
4656 main.log.exception( self.name + ": Uncaught exception!" )
4657 main.cleanup()
4658 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004659
4660 def getSwController( self, uri, jsonFormat=True ):
4661 """
4662 Descrition: Gets the controller information from the device
4663 """
4664 try:
4665 cmd = "device-controllers "
4666 if jsonFormat:
4667 cmd += "-j "
4668 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004669 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004670 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004671 return response
Jon Hallc6793552016-01-19 14:18:37 -08004672 except AssertionError:
4673 main.log.exception( "" )
4674 return None
GlennRC050596c2015-11-18 17:06:41 -08004675 except TypeError:
4676 main.log.exception( self.name + ": Object not as expected" )
4677 return None
4678 except pexpect.EOF:
4679 main.log.error( self.name + ": EOF exception found" )
4680 main.log.error( self.name + ": " + self.handle.before )
4681 main.cleanup()
4682 main.exit()
4683 except Exception:
4684 main.log.exception( self.name + ": Uncaught exception!" )
4685 main.cleanup()
4686 main.exit()
4687
4688 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4689 """
4690 Descrition: sets the controller(s) for the specified device
4691
4692 Parameters:
4693 Required: uri - String: The uri of the device(switch).
4694 ip - String or List: The ip address of the controller.
4695 This parameter can be formed in a couple of different ways.
4696 VALID:
4697 10.0.0.1 - just the ip address
4698 tcp:10.0.0.1 - the protocol and the ip address
4699 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4700 so that you can add controllers with different
4701 protocols and ports
4702 INVALID:
4703 10.0.0.1:6653 - this is not supported by ONOS
4704
4705 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4706 port - The port number.
4707 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4708
4709 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4710 """
4711 try:
4712 cmd = "device-setcontrollers"
4713
4714 if jsonFormat:
4715 cmd += " -j"
4716 cmd += " " + uri
4717 if isinstance( ip, str ):
4718 ip = [ip]
4719 for item in ip:
4720 if ":" in item:
4721 sitem = item.split( ":" )
4722 if len(sitem) == 3:
4723 cmd += " " + item
4724 elif "." in sitem[1]:
4725 cmd += " {}:{}".format(item, port)
4726 else:
4727 main.log.error( "Malformed entry: " + item )
4728 raise TypeError
4729 else:
4730 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004731 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004732 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004733 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004734 if "Error" in response:
4735 main.log.error( response )
4736 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004737 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004738 except AssertionError:
4739 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004740 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004741 except TypeError:
4742 main.log.exception( self.name + ": Object not as expected" )
4743 return main.FALSE
4744 except pexpect.EOF:
4745 main.log.error( self.name + ": EOF exception found" )
4746 main.log.error( self.name + ": " + self.handle.before )
4747 main.cleanup()
4748 main.exit()
4749 except Exception:
4750 main.log.exception( self.name + ": Uncaught exception!" )
4751 main.cleanup()
4752 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004753
4754 def removeDevice( self, device ):
4755 '''
4756 Description:
4757 Remove a device from ONOS by passing the uri of the device(s).
4758 Parameters:
4759 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4760 Returns:
4761 Returns main.FALSE if an exception is thrown or an error is present
4762 in the response. Otherwise, returns main.TRUE.
4763 NOTE:
4764 If a host cannot be removed, then this function will return main.FALSE
4765 '''
4766 try:
4767 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004768 deviceStr = device
4769 device = []
4770 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004771
4772 for d in device:
4773 time.sleep( 1 )
4774 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004775 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004776 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004777 if "Error" in response:
4778 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4779 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004780 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004781 except AssertionError:
4782 main.log.exception( "" )
4783 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004784 except TypeError:
4785 main.log.exception( self.name + ": Object not as expected" )
4786 return main.FALSE
4787 except pexpect.EOF:
4788 main.log.error( self.name + ": EOF exception found" )
4789 main.log.error( self.name + ": " + self.handle.before )
4790 main.cleanup()
4791 main.exit()
4792 except Exception:
4793 main.log.exception( self.name + ": Uncaught exception!" )
4794 main.cleanup()
4795 main.exit()
4796
4797 def removeHost( self, host ):
4798 '''
4799 Description:
4800 Remove a host from ONOS by passing the id of the host(s)
4801 Parameters:
4802 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4803 Returns:
4804 Returns main.FALSE if an exception is thrown or an error is present
4805 in the response. Otherwise, returns main.TRUE.
4806 NOTE:
4807 If a host cannot be removed, then this function will return main.FALSE
4808 '''
4809 try:
4810 if type( host ) is str:
4811 host = list( host )
4812
4813 for h in host:
4814 time.sleep( 1 )
4815 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004816 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004817 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004818 if "Error" in response:
4819 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4820 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004821 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004822 except AssertionError:
4823 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004824 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004825 except TypeError:
4826 main.log.exception( self.name + ": Object not as expected" )
4827 return main.FALSE
4828 except pexpect.EOF:
4829 main.log.error( self.name + ": EOF exception found" )
4830 main.log.error( self.name + ": " + self.handle.before )
4831 main.cleanup()
4832 main.exit()
4833 except Exception:
4834 main.log.exception( self.name + ": Uncaught exception!" )
4835 main.cleanup()
4836 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004837
YPZhangfebf7302016-05-24 16:45:56 -07004838 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004839 '''
4840 Description:
4841 Bring link down or up in the null-provider.
4842 params:
4843 begin - (string) One end of a device or switch.
4844 end - (string) the other end of the device or switch
4845 returns:
4846 main.TRUE if no exceptions were thrown and no Errors are
4847 present in the resoponse. Otherwise, returns main.FALSE
4848 '''
4849 try:
Jon Hallc6793552016-01-19 14:18:37 -08004850 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004851 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004852 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004853 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004854 if "Error" in response or "Failure" in response:
4855 main.log.error( response )
4856 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004858 except AssertionError:
4859 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004860 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004861 except TypeError:
4862 main.log.exception( self.name + ": Object not as expected" )
4863 return main.FALSE
4864 except pexpect.EOF:
4865 main.log.error( self.name + ": EOF exception found" )
4866 main.log.error( self.name + ": " + self.handle.before )
4867 main.cleanup()
4868 main.exit()
4869 except Exception:
4870 main.log.exception( self.name + ": Uncaught exception!" )
4871 main.cleanup()
4872 main.exit()
4873
Jon Hall2c8959e2016-12-16 12:17:34 -08004874 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004875 '''
4876 Description:
4877 Changes the state of port in an OF switch by means of the
4878 PORTSTATUS OF messages.
4879 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004880 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4881 port - (string) target port in the device. Ex: '2'
4882 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004883 returns:
4884 main.TRUE if no exceptions were thrown and no Errors are
4885 present in the resoponse. Otherwise, returns main.FALSE
4886 '''
4887 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004888 state = state.lower()
4889 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004890 cmd = "portstate {} {} {}".format( dpid, port, state )
4891 response = self.sendline( cmd, showResponse=True )
4892 assert response is not None, "Error in sendline"
4893 assert "Command not found:" not in response, response
4894 if "Error" in response or "Failure" in response:
4895 main.log.error( response )
4896 return main.FALSE
4897 return main.TRUE
4898 except AssertionError:
4899 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004900 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004901 except TypeError:
4902 main.log.exception( self.name + ": Object not as expected" )
4903 return main.FALSE
4904 except pexpect.EOF:
4905 main.log.error( self.name + ": EOF exception found" )
4906 main.log.error( self.name + ": " + self.handle.before )
4907 main.cleanup()
4908 main.exit()
4909 except Exception:
4910 main.log.exception( self.name + ": Uncaught exception!" )
4911 main.cleanup()
4912 main.exit()
4913
4914 def logSet( self, level="INFO", app="org.onosproject" ):
4915 """
4916 Set the logging level to lvl for a specific app
4917 returns main.TRUE on success
4918 returns main.FALSE if Error occurred
4919 if noExit is True, TestON will not exit, but clean up
4920 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4921 Level defaults to INFO
4922 """
4923 try:
4924 self.handle.sendline( "log:set %s %s" %( level, app ) )
4925 self.handle.expect( "onos>" )
4926
4927 response = self.handle.before
4928 if re.search( "Error", response ):
4929 return main.FALSE
4930 return main.TRUE
4931 except pexpect.TIMEOUT:
4932 main.log.exception( self.name + ": TIMEOUT exception found" )
4933 main.cleanup()
4934 main.exit()
4935 except pexpect.EOF:
4936 main.log.error( self.name + ": EOF exception found" )
4937 main.log.error( self.name + ": " + self.handle.before )
4938 main.cleanup()
4939 main.exit()
4940 except Exception:
4941 main.log.exception( self.name + ": Uncaught exception!" )
4942 main.cleanup()
4943 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004944
4945 def getGraphDict( self, timeout=60, includeHost=False ):
4946 """
4947 Return a dictionary which describes the latest network topology data as a
4948 graph.
4949 An example of the dictionary:
4950 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4951 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4952 Each vertex should at least have an 'edges' attribute which describes the
4953 adjacency information. The value of 'edges' attribute is also represented by
4954 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4955 list of attributes.
4956 An example of the edges dictionary:
4957 'edges': { vertex2: { 'port': ..., 'weight': ... },
4958 vertex3: { 'port': ..., 'weight': ... } }
4959 If includeHost == True, all hosts (and host-switch links) will be included
4960 in topology data.
4961 """
4962 graphDict = {}
4963 try:
4964 links = self.links()
4965 links = json.loads( links )
4966 devices = self.devices()
4967 devices = json.loads( devices )
4968 idToDevice = {}
4969 for device in devices:
4970 idToDevice[ device[ 'id' ] ] = device
4971 if includeHost:
4972 hosts = self.hosts()
4973 # FIXME: support 'includeHost' argument
4974 for link in links:
4975 nodeA = link[ 'src' ][ 'device' ]
4976 nodeB = link[ 'dst' ][ 'device' ]
4977 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4978 if not nodeA in graphDict.keys():
4979 graphDict[ nodeA ] = { 'edges':{},
4980 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4981 'type':idToDevice[ nodeA ][ 'type' ],
4982 'available':idToDevice[ nodeA ][ 'available' ],
4983 'role':idToDevice[ nodeA ][ 'role' ],
4984 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4985 'hw':idToDevice[ nodeA ][ 'hw' ],
4986 'sw':idToDevice[ nodeA ][ 'sw' ],
4987 'serial':idToDevice[ nodeA ][ 'serial' ],
4988 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4989 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4990 else:
4991 # Assert nodeB is not connected to any current links of nodeA
4992 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4993 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4994 'type':link[ 'type' ],
4995 'state':link[ 'state' ] }
4996 return graphDict
4997 except ( TypeError, ValueError ):
4998 main.log.exception( self.name + ": Object not as expected" )
4999 return None
5000 except KeyError:
5001 main.log.exception( self.name + ": KeyError exception found" )
5002 return None
5003 except AssertionError:
5004 main.log.exception( self.name + ": AssertionError exception found" )
5005 return None
5006 except pexpect.EOF:
5007 main.log.error( self.name + ": EOF exception found" )
5008 main.log.error( self.name + ": " + self.handle.before )
5009 return None
5010 except Exception:
5011 main.log.exception( self.name + ": Uncaught exception!" )
5012 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005013
5014 def getIntentPerfSummary( self ):
5015 '''
5016 Send command to check intent-perf summary
5017 Returns: dictionary for intent-perf summary
5018 if something wrong, function will return None
5019 '''
5020 cmd = "intent-perf -s"
5021 respDic = {}
5022 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005023 assert resp is not None, "Error in sendline"
5024 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005025 try:
5026 # Generate the dictionary to return
5027 for l in resp.split( "\n" ):
5028 # Delete any white space in line
5029 temp = re.sub( r'\s+', '', l )
5030 temp = temp.split( ":" )
5031 respDic[ temp[0] ] = temp[ 1 ]
5032
5033 except (TypeError, ValueError):
5034 main.log.exception( self.name + ": Object not as expected" )
5035 return None
5036 except KeyError:
5037 main.log.exception( self.name + ": KeyError exception found" )
5038 return None
5039 except AssertionError:
5040 main.log.exception( self.name + ": AssertionError exception found" )
5041 return None
5042 except pexpect.EOF:
5043 main.log.error( self.name + ": EOF exception found" )
5044 main.log.error( self.name + ": " + self.handle.before )
5045 return None
5046 except Exception:
5047 main.log.exception( self.name + ": Uncaught exception!" )
5048 return None
5049 return respDic
5050
Chiyu Chengec63bde2016-11-17 18:11:36 -08005051 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005052 """
5053 Searches the latest ONOS log file for the given search term and
5054 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005055
chengchiyu08303a02016-09-08 17:40:26 -07005056 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005057 searchTerm:
5058 The string to grep from the ONOS log.
5059 startLine:
5060 The term that decides which line is the start to search the searchTerm in
5061 the karaf log. For now, startTerm only works in 'first' mode.
5062 logNum:
5063 In some extreme cases, one karaf log is not big enough to contain all the
5064 information.Because of this, search mutiply logs is necessary to capture
5065 the right result. logNum is the number of karaf logs that we need to search
5066 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005067 mode:
5068 all: return all the strings that contain the search term
5069 last: return the last string that contains the search term
5070 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005071 num: return the number of times that the searchTerm appears in the log
5072 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005073 """
5074 try:
5075 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005076 #Build the log paths string
5077 logPath = '/opt/onos/log/karaf.log.'
5078 logPaths = '/opt/onos/log/karaf.log'
5079 for i in range( 1, logNum ):
5080 logPaths = logPath + str( i ) + " " + logPaths
5081 cmd = "cat " + logPaths
5082 if mode == 'all':
5083 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005084 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005085 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005086 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005087 if startLine != '':
5088 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5089 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5090 else:
5091 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005092 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005093 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005094 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005095 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005096 if mode == 'total':
5097 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5098 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005099 before = self.sendline( cmd )
5100 before = before.splitlines()
5101 # make sure the returned list only contains the search term
5102 returnLines = [line for line in before if searchTerm in line]
5103 return returnLines
5104 except AssertionError:
5105 main.log.error( self.name + " searchTerm is not string type" )
5106 return None
5107 except pexpect.EOF:
5108 main.log.error( self.name + ": EOF exception found" )
5109 main.log.error( self.name + ": " + self.handle.before )
5110 main.cleanup()
5111 main.exit()
5112 except pexpect.TIMEOUT:
5113 main.log.error( self.name + ": TIMEOUT exception found" )
5114 main.log.error( self.name + ": " + self.handle.before )
5115 main.cleanup()
5116 main.exit()
5117 except Exception:
5118 main.log.exception( self.name + ": Uncaught exception!" )
5119 main.cleanup()
5120 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005121
5122 def vplsShow( self, jsonFormat=True ):
5123 """
5124 Description: Returns result of onos:vpls show, which should list the
5125 configured VPLS networks and the assigned interfaces.
5126 Optional:
5127 * jsonFormat: enable json formatting of output
5128 Returns:
5129 The output of the command or None on error.
5130 """
5131 try:
5132 cmdStr = "vpls show"
5133 if jsonFormat:
5134 raise NotImplementedError
5135 cmdStr += " -j"
5136 handle = self.sendline( cmdStr )
5137 assert handle is not None, "Error in sendline"
5138 assert "Command not found:" not in handle, handle
5139 return handle
5140 except AssertionError:
5141 main.log.exception( "" )
5142 return None
5143 except TypeError:
5144 main.log.exception( self.name + ": Object not as expected" )
5145 return None
5146 except pexpect.EOF:
5147 main.log.error( self.name + ": EOF exception found" )
5148 main.log.error( self.name + ": " + self.handle.before )
5149 main.cleanup()
5150 main.exit()
5151 except NotImplementedError:
5152 main.log.exception( self.name + ": Json output not supported")
5153 return None
5154 except Exception:
5155 main.log.exception( self.name + ": Uncaught exception!" )
5156 main.cleanup()
5157 main.exit()
5158
5159 def parseVplsShow( self ):
5160 """
5161 Parse the cli output of 'vpls show' into json output. This is required
5162 as there is currently no json output available.
5163 """
5164 try:
5165 output = []
5166 raw = self.vplsShow( jsonFormat=False )
5167 namePat = "VPLS name: (?P<name>\w+)"
5168 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5169 encapPat = "Encapsulation: (?P<encap>\w+)"
5170 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5171 mIter = re.finditer( pattern, raw )
5172 for match in mIter:
5173 item = {}
5174 item[ 'name' ] = match.group( 'name' )
5175 ifaces = match.group( 'interfaces' ).split( ', ')
5176 if ifaces == [ "" ]:
5177 ifaces = []
5178 item[ 'interfaces' ] = ifaces
5179 encap = match.group( 'encap' )
5180 if encap != 'NONE':
5181 item[ 'encapsulation' ] = encap.lower()
5182 output.append( item )
5183 return output
5184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
5186 main.cleanup()
5187 main.exit()
5188
5189 def vplsList( self, jsonFormat=True ):
5190 """
5191 Description: Returns result of onos:vpls list, which should list the
5192 configured VPLS networks.
5193 Optional:
5194 * jsonFormat: enable json formatting of output
5195 """
5196 try:
5197 cmdStr = "vpls list"
5198 if jsonFormat:
5199 raise NotImplementedError
5200 cmdStr += " -j"
5201 handle = self.sendline( cmdStr )
5202 assert handle is not None, "Error in sendline"
5203 assert "Command not found:" not in handle, handle
5204 return handle
5205 except AssertionError:
5206 main.log.exception( "" )
5207 return None
5208 except TypeError:
5209 main.log.exception( self.name + ": Object not as expected" )
5210 return None
5211 except pexpect.EOF:
5212 main.log.error( self.name + ": EOF exception found" )
5213 main.log.error( self.name + ": " + self.handle.before )
5214 main.cleanup()
5215 main.exit()
5216 except NotImplementedError:
5217 main.log.exception( self.name + ": Json output not supported")
5218 return None
5219 except Exception:
5220 main.log.exception( self.name + ": Uncaught exception!" )
5221 main.cleanup()
5222 main.exit()
5223
5224 def vplsCreate( self, network ):
5225 """
5226 CLI command to create a new VPLS network.
5227 Required arguments:
5228 network - String name of the network to create.
5229 returns:
5230 main.TRUE on success and main.FALSE on failure
5231 """
5232 try:
5233 network = str( network )
5234 cmdStr = "vpls create "
5235 cmdStr += network
5236 output = self.sendline( cmdStr )
5237 assert output is not None, "Error in sendline"
5238 assert "Command not found:" not in output, output
5239 assert "Error executing command" not in output, output
5240 assert "VPLS already exists:" not in output, output
5241 return main.TRUE
5242 except AssertionError:
5243 main.log.exception( "" )
5244 return main.FALSE
5245 except TypeError:
5246 main.log.exception( self.name + ": Object not as expected" )
5247 return main.FALSE
5248 except pexpect.EOF:
5249 main.log.error( self.name + ": EOF exception found" )
5250 main.log.error( self.name + ": " + self.handle.before )
5251 main.cleanup()
5252 main.exit()
5253 except Exception:
5254 main.log.exception( self.name + ": Uncaught exception!" )
5255 main.cleanup()
5256 main.exit()
5257
5258 def vplsDelete( self, network ):
5259 """
5260 CLI command to delete a VPLS network.
5261 Required arguments:
5262 network - Name of the network to delete.
5263 returns:
5264 main.TRUE on success and main.FALSE on failure
5265 """
5266 try:
5267 network = str( network )
5268 cmdStr = "vpls delete "
5269 cmdStr += network
5270 output = self.sendline( cmdStr )
5271 assert output is not None, "Error in sendline"
5272 assert "Command not found:" not in output, output
5273 assert "Error executing command" not in output, output
5274 assert " not found" not in output, output
5275 return main.TRUE
5276 except AssertionError:
5277 main.log.exception( "" )
5278 return main.FALSE
5279 except TypeError:
5280 main.log.exception( self.name + ": Object not as expected" )
5281 return main.FALSE
5282 except pexpect.EOF:
5283 main.log.error( self.name + ": EOF exception found" )
5284 main.log.error( self.name + ": " + self.handle.before )
5285 main.cleanup()
5286 main.exit()
5287 except Exception:
5288 main.log.exception( self.name + ": Uncaught exception!" )
5289 main.cleanup()
5290 main.exit()
5291
5292 def vplsAddIface( self, network, iface ):
5293 """
5294 CLI command to add an interface to a VPLS network.
5295 Required arguments:
5296 network - Name of the network to add the interface to.
5297 iface - The ONOS name for an interface.
5298 returns:
5299 main.TRUE on success and main.FALSE on failure
5300 """
5301 try:
5302 network = str( network )
5303 iface = str( iface )
5304 cmdStr = "vpls add-if "
5305 cmdStr += network + " " + iface
5306 output = self.sendline( cmdStr )
5307 assert output is not None, "Error in sendline"
5308 assert "Command not found:" not in output, output
5309 assert "Error executing command" not in output, output
5310 assert "already associated to network" not in output, output
5311 assert "Interface cannot be added." not in output, output
5312 return main.TRUE
5313 except AssertionError:
5314 main.log.exception( "" )
5315 return main.FALSE
5316 except TypeError:
5317 main.log.exception( self.name + ": Object not as expected" )
5318 return main.FALSE
5319 except pexpect.EOF:
5320 main.log.error( self.name + ": EOF exception found" )
5321 main.log.error( self.name + ": " + self.handle.before )
5322 main.cleanup()
5323 main.exit()
5324 except Exception:
5325 main.log.exception( self.name + ": Uncaught exception!" )
5326 main.cleanup()
5327 main.exit()
5328
5329 def vplsRemIface( self, network, iface ):
5330 """
5331 CLI command to remove an interface from a VPLS network.
5332 Required arguments:
5333 network - Name of the network to remove the interface from.
5334 iface - Name of the interface to remove.
5335 returns:
5336 main.TRUE on success and main.FALSE on failure
5337 """
5338 try:
5339 iface = str( iface )
5340 cmdStr = "vpls rem-if "
5341 cmdStr += network + " " + iface
5342 output = self.sendline( cmdStr )
5343 assert output is not None, "Error in sendline"
5344 assert "Command not found:" not in output, output
5345 assert "Error executing command" not in output, output
5346 assert "is not configured" not in output, output
5347 return main.TRUE
5348 except AssertionError:
5349 main.log.exception( "" )
5350 return main.FALSE
5351 except TypeError:
5352 main.log.exception( self.name + ": Object not as expected" )
5353 return main.FALSE
5354 except pexpect.EOF:
5355 main.log.error( self.name + ": EOF exception found" )
5356 main.log.error( self.name + ": " + self.handle.before )
5357 main.cleanup()
5358 main.exit()
5359 except Exception:
5360 main.log.exception( self.name + ": Uncaught exception!" )
5361 main.cleanup()
5362 main.exit()
5363
5364 def vplsClean( self ):
5365 """
5366 Description: Clears the VPLS app configuration.
5367 Returns: main.TRUE on success and main.FALSE on failure
5368 """
5369 try:
5370 cmdStr = "vpls clean"
5371 handle = self.sendline( cmdStr )
5372 assert handle is not None, "Error in sendline"
5373 assert "Command not found:" not in handle, handle
5374 return handle
5375 except AssertionError:
5376 main.log.exception( "" )
5377 return main.FALSE
5378 except TypeError:
5379 main.log.exception( self.name + ": Object not as expected" )
5380 return main.FALSE
5381 except pexpect.EOF:
5382 main.log.error( self.name + ": EOF exception found" )
5383 main.log.error( self.name + ": " + self.handle.before )
5384 main.cleanup()
5385 main.exit()
5386 except Exception:
5387 main.log.exception( self.name + ": Uncaught exception!" )
5388 main.cleanup()
5389 main.exit()
5390
5391 def vplsSetEncap( self, network, encapType ):
5392 """
5393 CLI command to add an interface to a VPLS network.
5394 Required arguments:
5395 network - Name of the network to create.
5396 encapType - Type of encapsulation.
5397 returns:
5398 main.TRUE on success and main.FALSE on failure
5399 """
5400 try:
5401 network = str( network )
5402 encapType = str( encapType ).upper()
5403 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5404 cmdStr = "vpls set-encap "
5405 cmdStr += network + " " + encapType
5406 output = self.sendline( cmdStr )
5407 assert output is not None, "Error in sendline"
5408 assert "Command not found:" not in output, output
5409 assert "Error executing command" not in output, output
5410 assert "already associated to network" not in output, output
5411 assert "Encapsulation type " not in output, output
5412 return main.TRUE
5413 except AssertionError:
5414 main.log.exception( "" )
5415 return main.FALSE
5416 except TypeError:
5417 main.log.exception( self.name + ": Object not as expected" )
5418 return main.FALSE
5419 except pexpect.EOF:
5420 main.log.error( self.name + ": EOF exception found" )
5421 main.log.error( self.name + ": " + self.handle.before )
5422 main.cleanup()
5423 main.exit()
5424 except Exception:
5425 main.log.exception( self.name + ": Uncaught exception!" )
5426 main.cleanup()
5427 main.exit()
5428
5429 def interfaces( self, jsonFormat=True ):
5430 """
5431 Description: Returns result of interfaces command.
5432 Optional:
5433 * jsonFormat: enable json formatting of output
5434 Returns:
5435 The output of the command or None on error.
5436 """
5437 try:
5438 cmdStr = "interfaces"
5439 if jsonFormat:
5440 #raise NotImplementedError
5441 cmdStr += " -j"
5442 handle = self.sendline( cmdStr )
5443 assert handle is not None, "Error in sendline"
5444 assert "Command not found:" not in handle, handle
5445 return handle
5446 except AssertionError:
5447 main.log.exception( "" )
5448 return None
5449 except TypeError:
5450 main.log.exception( self.name + ": Object not as expected" )
5451 return None
5452 except pexpect.EOF:
5453 main.log.error( self.name + ": EOF exception found" )
5454 main.log.error( self.name + ": " + self.handle.before )
5455 main.cleanup()
5456 main.exit()
5457 except NotImplementedError:
5458 main.log.exception( self.name + ": Json output not supported")
5459 return None
5460 except Exception:
5461 main.log.exception( self.name + ": Uncaught exception!" )
5462 main.cleanup()
5463 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005464
5465 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5466 '''
5467 Get the timestamp of searchTerm from karaf log.
5468
5469 Arguments:
5470 splitTerm_before and splitTerm_after:
5471
5472 The terms that split the string that contains the timeStamp of
5473 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5474 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5475 and the splitTerm_after is "x"
5476
5477 others:
5478
5479 plz look at the "logsearch" Function in onosclidriver.py
5480
5481
5482 '''
5483 if logNum < 0:
5484 main.log.error("Get wrong log number ")
5485 return main.ERROR
5486 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5487 if len(lines) == 0:
5488 main.log.warn( "Captured timestamp string is empty" )
5489 return main.ERROR
5490 lines = lines[ 0 ]
5491 try:
5492 assert type(lines) is str
5493 # get the target value
5494 line = lines.split( splitTerm_before )
5495 key = line[ 1 ].split( splitTerm_after )
5496 return int( key[ 0 ] )
5497 except IndexError:
5498 main.log.warn( "Index Error!" )
5499 return main.ERROR
5500 except AssertionError:
5501 main.log.warn( "Search Term Not Found " )
5502 return main.ERROR