blob: 3a9a3c9e2c6992fbc3e37b903db359fdbb37f5fe [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
YPZhangebf9eb52016-05-12 15:20:24 -0700400 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
kelvin-onlab9f541032015-02-04 16:19:53 -0800408 """
409 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800410 lvlStr = ""
411 if level:
412 lvlStr = "--level=" + level
413
kelvin-onlab338f5512015-02-06 10:53:16 -0800414 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700415 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800416 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800417
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 response = self.handle.before
419 if re.search( "Error", response ):
420 return main.FALSE
421 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700422 except pexpect.TIMEOUT:
423 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700424 if noExit:
425 main.cleanup()
426 return None
427 else:
428 main.cleanup()
429 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800430 except pexpect.EOF:
431 main.log.error( self.name + ": EOF exception found" )
432 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700433 if noExit:
434 main.cleanup()
435 return None
436 else:
437 main.cleanup()
438 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800439 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800440 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit:
442 main.cleanup()
443 return None
444 else:
445 main.cleanup()
446 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400447
YPZhangebf9eb52016-05-12 15:20:24 -0700448 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800449 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800450 Send a completely user specified string to
451 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400452 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800453
YPZhang14a4aa92016-07-15 13:37:15 -0700454 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700455
andrewonlaba18f6bf2014-10-13 19:31:54 -0400456 Warning: There are no sanity checking to commands
457 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800458
kelvin8ec71442015-01-15 16:57:00 -0800459 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400460 try:
Jon Halla495f562016-05-16 18:03:26 -0700461 # Try to reconnect if disconnected from cli
462 self.handle.sendline( "" )
463 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
464 if i == 1:
465 main.log.error( self.name + ": onos cli session closed. ")
466 if self.onosIp:
467 main.log.warn( "Trying to reconnect " + self.onosIp )
468 reconnectResult = self.startOnosCli( self.onosIp )
469 if reconnectResult:
470 main.log.info( self.name + ": onos cli session reconnected." )
471 else:
472 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700473 if noExit:
474 return None
475 else:
476 main.cleanup()
477 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700478 else:
479 main.cleanup()
480 main.exit()
481 if i == 2:
482 self.handle.sendline( "" )
483 self.handle.expect( "onos>" )
484
Jon Hall14a03b52016-05-11 12:07:30 -0700485 if debug:
486 # NOTE: This adds and average of .4 seconds per call
487 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700488 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800489 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800490 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800491 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800492 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800493 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
494 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700495 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700496 main.log.debug( self.name + ": Raw output" )
497 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498
499 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800500 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800501 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700502 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700503 main.log.debug( self.name + ": ansiEscape output" )
504 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505
kelvin-onlabfb521662015-02-27 09:52:40 -0800506 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800507 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700509 main.log.debug( self.name + ": Removed extra returns " +
510 "from output" )
511 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700512
513 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800514 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": parsed and stripped output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
Jon Hall63604932015-02-26 17:09:50 -0800519 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700520 output = response.split( cmdStr.strip(), 1 )
521 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700522 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700524 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800525 output = output[1].strip()
526 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800527 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800528 return output
GlennRCed771242016-01-13 17:02:47 -0800529 except pexpect.TIMEOUT:
530 main.log.error( self.name + ":ONOS timeout" )
531 if debug:
532 main.log.debug( self.handle.before )
533 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 except IndexError:
535 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700536 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700537 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800538 except TypeError:
539 main.log.exception( self.name + ": Object not as expected" )
540 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400541 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800542 main.log.error( self.name + ": EOF exception found" )
543 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700544 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700545 return None
546 else:
547 main.cleanup()
548 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800549 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800550 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700551 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700552 return None
553 else:
554 main.cleanup()
555 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400556
kelvin8ec71442015-01-15 16:57:00 -0800557 # IMPORTANT NOTE:
558 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 # the cli command changing 'a:b' with 'aB'.
560 # Ex ) onos:topology > onosTopology
561 # onos:links > onosLinks
562 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800563
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800565 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 Adds a new cluster node by ID and address information.
567 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 * nodeId
569 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400570 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800572 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400573 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 cmdStr = "add-node " + str( nodeId ) + " " +\
575 str( ONOSIp ) + " " + str( tcpPort )
576 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700577 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800578 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800579 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800580 main.log.error( "Error in adding node" )
581 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800582 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400583 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800584 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400585 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800586 except AssertionError:
587 main.log.exception( "" )
588 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800589 except TypeError:
590 main.log.exception( self.name + ": Object not as expected" )
591 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 main.cleanup()
596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800598 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400599 main.cleanup()
600 main.exit()
601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
andrewonlab86dc3082014-10-13 18:18:38 -0400604 Removes a cluster by ID
605 Issues command: 'remove-node [<node-id>]'
606 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800607 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800608 """
andrewonlab86dc3082014-10-13 18:18:38 -0400609 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400610
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700612 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700613 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800614 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700615 if re.search( "Error", handle ):
616 main.log.error( "Error in removing node" )
617 main.log.error( handle )
618 return main.FALSE
619 else:
620 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800621 except AssertionError:
622 main.log.exception( "" )
623 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800624 except TypeError:
625 main.log.exception( self.name + ": Object not as expected" )
626 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400627 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800628 main.log.error( self.name + ": EOF exception found" )
629 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400630 main.cleanup()
631 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800632 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800633 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400634 main.cleanup()
635 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400636
Jon Hall61282e32015-03-19 11:34:11 -0700637 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800638 """
andrewonlab7c211572014-10-15 16:45:20 -0400639 List the nodes currently visible
640 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700641 Optional argument:
642 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800643 """
andrewonlab7c211572014-10-15 16:45:20 -0400644 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700645 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700646 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700647 cmdStr += " -j"
648 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700649 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800650 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700651 return output
Jon Hallc6793552016-01-19 14:18:37 -0800652 except AssertionError:
653 main.log.exception( "" )
654 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800655 except TypeError:
656 main.log.exception( self.name + ": Object not as expected" )
657 return None
andrewonlab7c211572014-10-15 16:45:20 -0400658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800659 main.log.error( self.name + ": EOF exception found" )
660 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400661 main.cleanup()
662 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800663 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800664 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400665 main.cleanup()
666 main.exit()
667
kelvin8ec71442015-01-15 16:57:00 -0800668 def topology( self ):
669 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700670 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700671 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700672 Return:
673 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800674 """
andrewonlab95ce8322014-10-13 14:12:04 -0400675 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700676 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800678 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700679 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400680 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800681 except AssertionError:
682 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800683 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800684 except TypeError:
685 main.log.exception( self.name + ": Object not as expected" )
686 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400687 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800688 main.log.error( self.name + ": EOF exception found" )
689 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400690 main.cleanup()
691 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800692 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800693 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400694 main.cleanup()
695 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800696
jenkins7ead5a82015-03-13 10:28:21 -0700697 def deviceRemove( self, deviceId ):
698 """
699 Removes particular device from storage
700
701 TODO: refactor this function
702 """
703 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700704 cmdStr = "device-remove " + str( deviceId )
705 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800706 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700707 if re.search( "Error", handle ):
708 main.log.error( "Error in removing device" )
709 main.log.error( handle )
710 return main.FALSE
711 else:
712 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800713 except AssertionError:
714 main.log.exception( "" )
715 return None
jenkins7ead5a82015-03-13 10:28:21 -0700716 except TypeError:
717 main.log.exception( self.name + ": Object not as expected" )
718 return None
719 except pexpect.EOF:
720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
722 main.cleanup()
723 main.exit()
724 except Exception:
725 main.log.exception( self.name + ": Uncaught exception!" )
726 main.cleanup()
727 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800730 """
Jon Hall7b02d952014-10-17 20:14:54 -0400731 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400732 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800734 """
andrewonlab86dc3082014-10-13 18:18:38 -0400735 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700736 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700738 cmdStr += " -j"
739 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800740 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800742 except AssertionError:
743 main.log.exception( "" )
744 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800745 except TypeError:
746 main.log.exception( self.name + ": Object not as expected" )
747 return None
andrewonlab7c211572014-10-15 16:45:20 -0400748 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800749 main.log.error( self.name + ": EOF exception found" )
750 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400751 main.cleanup()
752 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800753 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800754 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400755 main.cleanup()
756 main.exit()
757
kelvin-onlabd3b64892015-01-20 13:26:24 -0800758 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800759 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800760 This balances the devices across all controllers
761 by issuing command: 'onos> onos:balance-masters'
762 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800763 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800764 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700766 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800767 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700768 if re.search( "Error", handle ):
769 main.log.error( "Error in balancing masters" )
770 main.log.error( handle )
771 return main.FALSE
772 else:
773 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800774 except AssertionError:
775 main.log.exception( "" )
776 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800777 except TypeError:
778 main.log.exception( self.name + ": Object not as expected" )
779 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800780 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800781 main.log.error( self.name + ": EOF exception found" )
782 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800783 main.cleanup()
784 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800787 main.cleanup()
788 main.exit()
789
Jon Hallc6793552016-01-19 14:18:37 -0800790 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700791 """
792 Returns the output of the masters command.
793 Optional argument:
794 * jsonFormat - boolean indicating if you want output in json
795 """
796 try:
797 cmdStr = "onos:masters"
798 if jsonFormat:
799 cmdStr += " -j"
800 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700801 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800802 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700803 return output
Jon Hallc6793552016-01-19 14:18:37 -0800804 except AssertionError:
805 main.log.exception( "" )
806 return None
acsmars24950022015-07-30 18:00:43 -0700807 except TypeError:
808 main.log.exception( self.name + ": Object not as expected" )
809 return None
810 except pexpect.EOF:
811 main.log.error( self.name + ": EOF exception found" )
812 main.log.error( self.name + ": " + self.handle.before )
813 main.cleanup()
814 main.exit()
815 except Exception:
816 main.log.exception( self.name + ": Uncaught exception!" )
817 main.cleanup()
818 main.exit()
819
Jon Hallc6793552016-01-19 14:18:37 -0800820 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700821 """
822 Uses the master command to check that the devices' leadership
823 is evenly divided
824
825 Dependencies: checkMasters() and summary()
826
Jon Hall6509dbf2016-06-21 17:01:17 -0700827 Returns main.TRUE if the devices are balanced
828 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700829 Exits on Exception
830 Returns None on TypeError
831 """
832 try:
Jon Hallc6793552016-01-19 14:18:37 -0800833 summaryOutput = self.summary()
834 totalDevices = json.loads( summaryOutput )[ "devices" ]
835 except ( TypeError, ValueError ):
836 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
837 return None
838 try:
acsmars24950022015-07-30 18:00:43 -0700839 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800840 mastersOutput = self.checkMasters()
841 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700842 first = masters[ 0 ][ "size" ]
843 for master in masters:
844 totalOwnedDevices += master[ "size" ]
845 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
846 main.log.error( "Mastership not balanced" )
847 main.log.info( "\n" + self.checkMasters( False ) )
848 return main.FALSE
849 main.log.info( "Mastership balanced between " \
850 + str( len(masters) ) + " masters" )
851 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800852 except ( TypeError, ValueError ):
853 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700854 return None
855 except pexpect.EOF:
856 main.log.error( self.name + ": EOF exception found" )
857 main.log.error( self.name + ": " + self.handle.before )
858 main.cleanup()
859 main.exit()
860 except Exception:
861 main.log.exception( self.name + ": Uncaught exception!" )
862 main.cleanup()
863 main.exit()
864
YPZhangfebf7302016-05-24 16:45:56 -0700865 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800866 """
Jon Halle8217482014-10-17 13:49:14 -0400867 Lists all core links
868 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700872 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700874 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700875 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800876 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800878 except AssertionError:
879 main.log.exception( "" )
880 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800881 except TypeError:
882 main.log.exception( self.name + ": Object not as expected" )
883 return None
Jon Halle8217482014-10-17 13:49:14 -0400884 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800885 main.log.error( self.name + ": EOF exception found" )
886 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400887 main.cleanup()
888 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800889 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800890 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400891 main.cleanup()
892 main.exit()
893
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800895 """
Jon Halle8217482014-10-17 13:49:14 -0400896 Lists all ports
897 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800899 """
Jon Halle8217482014-10-17 13:49:14 -0400900 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700901 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr += " -j"
904 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800905 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800907 except AssertionError:
908 main.log.exception( "" )
909 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800910 except TypeError:
911 main.log.exception( self.name + ": Object not as expected" )
912 return None
Jon Halle8217482014-10-17 13:49:14 -0400913 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800914 main.log.error( self.name + ": EOF exception found" )
915 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400916 main.cleanup()
917 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800918 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800919 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400920 main.cleanup()
921 main.exit()
922
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800924 """
Jon Hall983a1702014-10-28 18:44:22 -0400925 Lists all devices and the controllers with roles assigned to them
926 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800928 """
andrewonlab7c211572014-10-15 16:45:20 -0400929 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700930 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr += " -j"
933 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800934 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700935 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800936 except AssertionError:
937 main.log.exception( "" )
938 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800939 except TypeError:
940 main.log.exception( self.name + ": Object not as expected" )
941 return None
Jon Hall983a1702014-10-28 18:44:22 -0400942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800943 main.log.error( self.name + ": EOF exception found" )
944 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400945 main.cleanup()
946 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800947 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800948 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400949 main.cleanup()
950 main.exit()
951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 Given the a string containing the json representation of the "roles"
955 cli command and a partial or whole device id, returns a json object
956 containing the roles output for the first device whose id contains
957 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400958
959 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800960 A dict of the role assignments for the given device or
961 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Hall983a1702014-10-28 18:44:22 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400965 return None
966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 rawRoles = self.roles()
968 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800969 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800971 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return device
974 return None
Jon Hallc6793552016-01-19 14:18:37 -0800975 except ( TypeError, ValueError ):
976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800977 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400981 main.cleanup()
982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400985 main.cleanup()
986 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800989 """
Jon Hall94fd0472014-12-08 11:52:42 -0800990 Iterates through each device and checks if there is a master assigned
991 Returns: main.TRUE if each device has a master
992 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800993 """
Jon Hall94fd0472014-12-08 11:52:42 -0800994 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 rawRoles = self.roles()
996 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800997 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800999 # print device
1000 if device[ 'master' ] == "none":
1001 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001002 return main.FALSE
1003 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001004 except ( TypeError, ValueError ):
1005 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001006 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001008 main.log.error( self.name + ": EOF exception found" )
1009 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001010 main.cleanup()
1011 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001012 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001013 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001014 main.cleanup()
1015 main.exit()
1016
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 Returns string of paths, and the cost.
1020 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001021 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001022 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1024 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001025 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001026 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( "Error in getting paths" )
1028 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 else:
kelvin8ec71442015-01-15 16:57:00 -08001030 path = handle.split( ";" )[ 0 ]
1031 cost = handle.split( ";" )[ 1 ]
1032 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001033 except AssertionError:
1034 main.log.exception( "" )
1035 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001036 except TypeError:
1037 main.log.exception( self.name + ": Object not as expected" )
1038 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001039 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.error( self.name + ": EOF exception found" )
1041 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001042 main.cleanup()
1043 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001044 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001045 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001046 main.cleanup()
1047 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001048
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hallffb386d2014-11-21 13:43:38 -08001051 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001052 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001054 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001056 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001058 cmdStr += " -j"
1059 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001060 if handle:
1061 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001062 # TODO: Maybe make this less hardcoded
1063 # ConsistentMap Exceptions
1064 assert "org.onosproject.store.service" not in handle
1065 # Node not leader
1066 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001068 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001069 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001070 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001071 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001072 except TypeError:
1073 main.log.exception( self.name + ": Object not as expected" )
1074 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001075 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001078 main.cleanup()
1079 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001080 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001081 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001082 main.cleanup()
1083 main.exit()
1084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001088
Jon Hallefbd9792015-03-05 16:11:36 -08001089 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 partial mac address
1091
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001093 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 try:
kelvin8ec71442015-01-15 16:57:00 -08001095 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 return None
1097 else:
1098 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 rawHosts = self.hosts()
1100 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001101 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001103 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001104 if not host:
1105 pass
1106 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001107 return host
1108 return None
Jon Hallc6793552016-01-19 14:18:37 -08001109 except ( TypeError, ValueError ):
1110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001111 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001115 main.cleanup()
1116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001117 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001118 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001119 main.cleanup()
1120 main.exit()
1121
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001123 """
1124 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001125 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001126
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 IMPORTANT:
1130 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001131 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001132 Furthermore, it assumes that value of VLAN is '-1'
1133 Description:
kelvin8ec71442015-01-15 16:57:00 -08001134 Converts mininet hosts ( h1, h2, h3... ) into
1135 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1136 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001137 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001141 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 hostHex = hex( int( host ) ).zfill( 12 )
1143 hostHex = str( hostHex ).replace( 'x', '0' )
1144 i = iter( str( hostHex ) )
1145 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1146 hostHex = hostHex + "/-1"
1147 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001150
Jon Halld4d4b372015-01-28 16:02:41 -08001151 except TypeError:
1152 main.log.exception( self.name + ": Object not as expected" )
1153 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001155 main.log.error( self.name + ": EOF exception found" )
1156 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157 main.cleanup()
1158 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001160 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001161 main.cleanup()
1162 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001163
Jeremy Songsterc032f162016-08-04 17:14:49 -07001164 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001165 """
andrewonlabe6745342014-10-17 14:29:13 -04001166 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 * hostIdOne: ONOS host id for host1
1168 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001169 Optional:
1170 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001171 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001172 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001173 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001174 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001175 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001176 Returns:
1177 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001178 """
andrewonlabe6745342014-10-17 14:29:13 -04001179 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001180 cmdStr = "add-host-intent "
1181 if vlanId:
1182 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001183 if setVlan:
1184 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001185 if encap:
1186 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001187 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001189 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001190 if re.search( "Error", handle ):
1191 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001192 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001194 else:
1195 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1197 match = re.search('id=0x([\da-f]+),', handle)
1198 if match:
1199 return match.group()[3:-1]
1200 else:
1201 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001202 main.log.debug( "Response from ONOS was: " +
1203 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001204 return None
Jon Hallc6793552016-01-19 14:18:37 -08001205 except AssertionError:
1206 main.log.exception( "" )
1207 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001208 except TypeError:
1209 main.log.exception( self.name + ": Object not as expected" )
1210 return None
andrewonlabe6745342014-10-17 14:29:13 -04001211 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001212 main.log.error( self.name + ": EOF exception found" )
1213 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001214 main.cleanup()
1215 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001217 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001218 main.cleanup()
1219 main.exit()
1220
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001222 """
andrewonlab7b31d232014-10-24 13:31:47 -04001223 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 * ingressDevice: device id of ingress device
1225 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001226 Optional:
1227 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001228 Description:
1229 Adds an optical intent by specifying an ingress and egress device
1230 Returns:
1231 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001232 """
andrewonlab7b31d232014-10-24 13:31:47 -04001233 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1235 " " + str( egressDevice )
1236 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001237 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001238 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001239 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 main.log.error( "Error in adding Optical intent" )
1241 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001242 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001243 main.log.info( "Optical intent installed between " +
1244 str( ingressDevice ) + " and " +
1245 str( egressDevice ) )
1246 match = re.search('id=0x([\da-f]+),', handle)
1247 if match:
1248 return match.group()[3:-1]
1249 else:
1250 main.log.error( "Error, intent ID not found" )
1251 return None
Jon Hallc6793552016-01-19 14:18:37 -08001252 except AssertionError:
1253 main.log.exception( "" )
1254 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001255 except TypeError:
1256 main.log.exception( self.name + ": Object not as expected" )
1257 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001258 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001259 main.log.error( self.name + ": EOF exception found" )
1260 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001261 main.cleanup()
1262 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001263 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001264 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001265 main.cleanup()
1266 main.exit()
1267
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 ingressDevice,
1271 egressDevice,
1272 portIngress="",
1273 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 ethType="",
1275 ethSrc="",
1276 ethDst="",
1277 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001278 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001279 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001280 ipProto="",
1281 ipSrc="",
1282 ipDst="",
1283 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001284 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001285 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001286 setVlan="",
1287 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001288 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001289 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 * ingressDevice: device id of ingress device
1291 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001292 Optional:
1293 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001294 * ethSrc: specify ethSrc ( i.e. src mac addr )
1295 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001296 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001298 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001299 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001300 * ipSrc: specify ip source address
1301 * ipDst: specify ip destination address
1302 * tcpSrc: specify tcp source port
1303 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001304 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001305 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001306 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001307 Description:
kelvin8ec71442015-01-15 16:57:00 -08001308 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001309 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001310 Returns:
1311 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001312
Jon Halle3f39ff2015-01-13 11:50:53 -08001313 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001314 options developers provide for point-to-point
1315 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001316 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001317 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001318 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001319
Jeremy Songsterff553672016-05-12 17:06:23 -07001320 if ethType:
1321 cmd += " --ethType " + str( ethType )
1322 if ethSrc:
1323 cmd += " --ethSrc " + str( ethSrc )
1324 if ethDst:
1325 cmd += " --ethDst " + str( ethDst )
1326 if bandwidth:
1327 cmd += " --bandwidth " + str( bandwidth )
1328 if lambdaAlloc:
1329 cmd += " --lambda "
1330 if ipProto:
1331 cmd += " --ipProto " + str( ipProto )
1332 if ipSrc:
1333 cmd += " --ipSrc " + str( ipSrc )
1334 if ipDst:
1335 cmd += " --ipDst " + str( ipDst )
1336 if tcpSrc:
1337 cmd += " --tcpSrc " + str( tcpSrc )
1338 if tcpDst:
1339 cmd += " --tcpDst " + str( tcpDst )
1340 if vlanId:
1341 cmd += " -v " + str( vlanId )
1342 if setVlan:
1343 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001344 if encap:
1345 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001346 if protected:
1347 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001348
kelvin8ec71442015-01-15 16:57:00 -08001349 # Check whether the user appended the port
1350 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 if "/" in ingressDevice:
1352 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001353 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001355 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001356 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 # Would it make sense to throw an exception and exit
1358 # the test?
1359 return None
andrewonlab36af3822014-11-18 17:48:18 -05001360
kelvin8ec71442015-01-15 16:57:00 -08001361 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 str( ingressDevice ) + "/" +\
1363 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001364
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if "/" in egressDevice:
1366 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001367 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001369 main.log.error( "You must specify the egress port" )
1370 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001371
kelvin8ec71442015-01-15 16:57:00 -08001372 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 str( egressDevice ) + "/" +\
1374 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001375
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001377 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001379 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001380 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001381 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001382 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001383 # TODO: print out all the options in this message?
1384 main.log.info( "Point-to-point intent installed between " +
1385 str( ingressDevice ) + " and " +
1386 str( egressDevice ) )
1387 match = re.search('id=0x([\da-f]+),', handle)
1388 if match:
1389 return match.group()[3:-1]
1390 else:
1391 main.log.error( "Error, intent ID not found" )
1392 return None
Jon Hallc6793552016-01-19 14:18:37 -08001393 except AssertionError:
1394 main.log.exception( "" )
1395 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001396 except TypeError:
1397 main.log.exception( self.name + ": Object not as expected" )
1398 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001399 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001400 main.log.error( self.name + ": EOF exception found" )
1401 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001402 main.cleanup()
1403 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001404 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001405 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001406 main.cleanup()
1407 main.exit()
1408
kelvin-onlabd3b64892015-01-20 13:26:24 -08001409 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001410 self,
shahshreyac2f97072015-03-19 17:04:29 -07001411 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001413 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001415 ethType="",
1416 ethSrc="",
1417 ethDst="",
1418 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001420 ipProto="",
1421 ipSrc="",
1422 ipDst="",
1423 tcpSrc="",
1424 tcpDst="",
1425 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001426 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001427 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001428 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001429 partial=False,
1430 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001431 """
shahshreyad0c80432014-12-04 16:56:05 -08001432 Note:
shahshreya70622b12015-03-19 17:19:00 -07001433 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001434 is same. That is, all ingress devices include port numbers
1435 with a "/" or all ingress devices could specify device
1436 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001437 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001438 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001439 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001440 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001441 Optional:
1442 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001443 * ethSrc: specify ethSrc ( i.e. src mac addr )
1444 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001445 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001447 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001448 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001449 * ipSrc: specify ip source address
1450 * ipDst: specify ip destination address
1451 * tcpSrc: specify tcp source port
1452 * tcpDst: specify tcp destination port
1453 * setEthSrc: action to Rewrite Source MAC Address
1454 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001455 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001456 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001457 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001458 Description:
kelvin8ec71442015-01-15 16:57:00 -08001459 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001460 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 Returns:
1462 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001463
Jon Halle3f39ff2015-01-13 11:50:53 -08001464 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001465 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001466 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001467 """
shahshreyad0c80432014-12-04 16:56:05 -08001468 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001469 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001470
Jeremy Songsterff553672016-05-12 17:06:23 -07001471 if ethType:
1472 cmd += " --ethType " + str( ethType )
1473 if ethSrc:
1474 cmd += " --ethSrc " + str( ethSrc )
1475 if ethDst:
1476 cmd += " --ethDst " + str( ethDst )
1477 if bandwidth:
1478 cmd += " --bandwidth " + str( bandwidth )
1479 if lambdaAlloc:
1480 cmd += " --lambda "
1481 if ipProto:
1482 cmd += " --ipProto " + str( ipProto )
1483 if ipSrc:
1484 cmd += " --ipSrc " + str( ipSrc )
1485 if ipDst:
1486 cmd += " --ipDst " + str( ipDst )
1487 if tcpSrc:
1488 cmd += " --tcpSrc " + str( tcpSrc )
1489 if tcpDst:
1490 cmd += " --tcpDst " + str( tcpDst )
1491 if setEthSrc:
1492 cmd += " --setEthSrc " + str( setEthSrc )
1493 if setEthDst:
1494 cmd += " --setEthDst " + str( setEthDst )
1495 if vlanId:
1496 cmd += " -v " + str( vlanId )
1497 if setVlan:
1498 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001499 if partial:
1500 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001501 if encap:
1502 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001503
kelvin8ec71442015-01-15 16:57:00 -08001504 # Check whether the user appended the port
1505 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001506
1507 if portIngressList is None:
1508 for ingressDevice in ingressDeviceList:
1509 if "/" in ingressDevice:
1510 cmd += " " + str( ingressDevice )
1511 else:
1512 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001513 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001514 # TODO: perhaps more meaningful return
1515 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001516 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001517 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001518 for ingressDevice, portIngress in zip( ingressDeviceList,
1519 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001520 cmd += " " + \
1521 str( ingressDevice ) + "/" +\
1522 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001523 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001524 main.log.error( "Device list and port list does not " +
1525 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001526 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 if "/" in egressDevice:
1528 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001529 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001531 main.log.error( "You must specify " +
1532 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001533 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001534
kelvin8ec71442015-01-15 16:57:00 -08001535 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 str( egressDevice ) + "/" +\
1537 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001538 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001539 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001540 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001541 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001542 main.log.error( "Error in adding multipoint-to-singlepoint " +
1543 "intent" )
1544 return None
shahshreyad0c80432014-12-04 16:56:05 -08001545 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001546 match = re.search('id=0x([\da-f]+),', handle)
1547 if match:
1548 return match.group()[3:-1]
1549 else:
1550 main.log.error( "Error, intent ID not found" )
1551 return None
Jon Hallc6793552016-01-19 14:18:37 -08001552 except AssertionError:
1553 main.log.exception( "" )
1554 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001555 except TypeError:
1556 main.log.exception( self.name + ": Object not as expected" )
1557 return None
1558 except pexpect.EOF:
1559 main.log.error( self.name + ": EOF exception found" )
1560 main.log.error( self.name + ": " + self.handle.before )
1561 main.cleanup()
1562 main.exit()
1563 except Exception:
1564 main.log.exception( self.name + ": Uncaught exception!" )
1565 main.cleanup()
1566 main.exit()
1567
1568 def addSinglepointToMultipointIntent(
1569 self,
1570 ingressDevice,
1571 egressDeviceList,
1572 portIngress="",
1573 portEgressList=None,
1574 ethType="",
1575 ethSrc="",
1576 ethDst="",
1577 bandwidth="",
1578 lambdaAlloc=False,
1579 ipProto="",
1580 ipSrc="",
1581 ipDst="",
1582 tcpSrc="",
1583 tcpDst="",
1584 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001585 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001586 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001587 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001588 partial=False,
1589 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001590 """
1591 Note:
1592 This function assumes the format of all egress devices
1593 is same. That is, all egress devices include port numbers
1594 with a "/" or all egress devices could specify device
1595 ids and port numbers seperately.
1596 Required:
1597 * EgressDeviceList: List of device ids of egress device
1598 ( Atleast 2 eress devices required in the list )
1599 * ingressDevice: device id of ingress device
1600 Optional:
1601 * ethType: specify ethType
1602 * ethSrc: specify ethSrc ( i.e. src mac addr )
1603 * ethDst: specify ethDst ( i.e. dst mac addr )
1604 * bandwidth: specify bandwidth capacity of link
1605 * lambdaAlloc: if True, intent will allocate lambda
1606 for the specified intent
1607 * ipProto: specify ip protocol
1608 * ipSrc: specify ip source address
1609 * ipDst: specify ip destination address
1610 * tcpSrc: specify tcp source port
1611 * tcpDst: specify tcp destination port
1612 * setEthSrc: action to Rewrite Source MAC Address
1613 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001614 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001615 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001616 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001617 Description:
1618 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1619 specifying device id's and optional fields
1620 Returns:
1621 A string of the intent id or None on error
1622
1623 NOTE: This function may change depending on the
1624 options developers provide for singlepoint-to-multipoint
1625 intent via cli
1626 """
1627 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001628 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001629
Jeremy Songsterff553672016-05-12 17:06:23 -07001630 if ethType:
1631 cmd += " --ethType " + str( ethType )
1632 if ethSrc:
1633 cmd += " --ethSrc " + str( ethSrc )
1634 if ethDst:
1635 cmd += " --ethDst " + str( ethDst )
1636 if bandwidth:
1637 cmd += " --bandwidth " + str( bandwidth )
1638 if lambdaAlloc:
1639 cmd += " --lambda "
1640 if ipProto:
1641 cmd += " --ipProto " + str( ipProto )
1642 if ipSrc:
1643 cmd += " --ipSrc " + str( ipSrc )
1644 if ipDst:
1645 cmd += " --ipDst " + str( ipDst )
1646 if tcpSrc:
1647 cmd += " --tcpSrc " + str( tcpSrc )
1648 if tcpDst:
1649 cmd += " --tcpDst " + str( tcpDst )
1650 if setEthSrc:
1651 cmd += " --setEthSrc " + str( setEthSrc )
1652 if setEthDst:
1653 cmd += " --setEthDst " + str( setEthDst )
1654 if vlanId:
1655 cmd += " -v " + str( vlanId )
1656 if setVlan:
1657 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001658 if partial:
1659 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001660 if encap:
1661 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001662
1663 # Check whether the user appended the port
1664 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001665
kelvin-onlabb9408212015-04-01 13:34:04 -07001666 if "/" in ingressDevice:
1667 cmd += " " + str( ingressDevice )
1668 else:
1669 if not portIngress:
1670 main.log.error( "You must specify " +
1671 "the Ingress port" )
1672 return main.FALSE
1673
1674 cmd += " " +\
1675 str( ingressDevice ) + "/" +\
1676 str( portIngress )
1677
1678 if portEgressList is None:
1679 for egressDevice in egressDeviceList:
1680 if "/" in egressDevice:
1681 cmd += " " + str( egressDevice )
1682 else:
1683 main.log.error( "You must specify " +
1684 "the egress port" )
1685 # TODO: perhaps more meaningful return
1686 return main.FALSE
1687 else:
1688 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001689 for egressDevice, portEgress in zip( egressDeviceList,
1690 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001691 cmd += " " + \
1692 str( egressDevice ) + "/" +\
1693 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001694 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001695 main.log.error( "Device list and port list does not " +
1696 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001697 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001698 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001699 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001700 # If error, return error message
1701 if re.search( "Error", handle ):
1702 main.log.error( "Error in adding singlepoint-to-multipoint " +
1703 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001704 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001705 else:
1706 match = re.search('id=0x([\da-f]+),', handle)
1707 if match:
1708 return match.group()[3:-1]
1709 else:
1710 main.log.error( "Error, intent ID not found" )
1711 return None
Jon Hallc6793552016-01-19 14:18:37 -08001712 except AssertionError:
1713 main.log.exception( "" )
1714 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001715 except TypeError:
1716 main.log.exception( self.name + ": Object not as expected" )
1717 return None
shahshreyad0c80432014-12-04 16:56:05 -08001718 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001719 main.log.error( self.name + ": EOF exception found" )
1720 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001721 main.cleanup()
1722 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001723 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001724 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001725 main.cleanup()
1726 main.exit()
1727
Hari Krishna9e232602015-04-13 17:29:08 -07001728 def addMplsIntent(
1729 self,
1730 ingressDevice,
1731 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001732 ingressPort="",
1733 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001734 ethType="",
1735 ethSrc="",
1736 ethDst="",
1737 bandwidth="",
1738 lambdaAlloc=False,
1739 ipProto="",
1740 ipSrc="",
1741 ipDst="",
1742 tcpSrc="",
1743 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001744 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001745 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001746 priority=""):
1747 """
1748 Required:
1749 * ingressDevice: device id of ingress device
1750 * egressDevice: device id of egress device
1751 Optional:
1752 * ethType: specify ethType
1753 * ethSrc: specify ethSrc ( i.e. src mac addr )
1754 * ethDst: specify ethDst ( i.e. dst mac addr )
1755 * bandwidth: specify bandwidth capacity of link
1756 * lambdaAlloc: if True, intent will allocate lambda
1757 for the specified intent
1758 * ipProto: specify ip protocol
1759 * ipSrc: specify ip source address
1760 * ipDst: specify ip destination address
1761 * tcpSrc: specify tcp source port
1762 * tcpDst: specify tcp destination port
1763 * ingressLabel: Ingress MPLS label
1764 * egressLabel: Egress MPLS label
1765 Description:
1766 Adds MPLS intent by
1767 specifying device id's and optional fields
1768 Returns:
1769 A string of the intent id or None on error
1770
1771 NOTE: This function may change depending on the
1772 options developers provide for MPLS
1773 intent via cli
1774 """
1775 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001776 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001777
Jeremy Songsterff553672016-05-12 17:06:23 -07001778 if ethType:
1779 cmd += " --ethType " + str( ethType )
1780 if ethSrc:
1781 cmd += " --ethSrc " + str( ethSrc )
1782 if ethDst:
1783 cmd += " --ethDst " + str( ethDst )
1784 if bandwidth:
1785 cmd += " --bandwidth " + str( bandwidth )
1786 if lambdaAlloc:
1787 cmd += " --lambda "
1788 if ipProto:
1789 cmd += " --ipProto " + str( ipProto )
1790 if ipSrc:
1791 cmd += " --ipSrc " + str( ipSrc )
1792 if ipDst:
1793 cmd += " --ipDst " + str( ipDst )
1794 if tcpSrc:
1795 cmd += " --tcpSrc " + str( tcpSrc )
1796 if tcpDst:
1797 cmd += " --tcpDst " + str( tcpDst )
1798 if ingressLabel:
1799 cmd += " --ingressLabel " + str( ingressLabel )
1800 if egressLabel:
1801 cmd += " --egressLabel " + str( egressLabel )
1802 if priority:
1803 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 # Check whether the user appended the port
1806 # or provided it as an input
1807 if "/" in ingressDevice:
1808 cmd += " " + str( ingressDevice )
1809 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001810 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001811 main.log.error( "You must specify the ingress port" )
1812 return None
1813
1814 cmd += " " + \
1815 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001816 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001817
1818 if "/" in egressDevice:
1819 cmd += " " + str( egressDevice )
1820 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001821 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001822 main.log.error( "You must specify the egress port" )
1823 return None
1824
1825 cmd += " " +\
1826 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001827 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001828
1829 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001830 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001831 # If error, return error message
1832 if re.search( "Error", handle ):
1833 main.log.error( "Error in adding mpls intent" )
1834 return None
1835 else:
1836 # TODO: print out all the options in this message?
1837 main.log.info( "MPLS intent installed between " +
1838 str( ingressDevice ) + " and " +
1839 str( egressDevice ) )
1840 match = re.search('id=0x([\da-f]+),', handle)
1841 if match:
1842 return match.group()[3:-1]
1843 else:
1844 main.log.error( "Error, intent ID not found" )
1845 return None
Jon Hallc6793552016-01-19 14:18:37 -08001846 except AssertionError:
1847 main.log.exception( "" )
1848 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001849 except TypeError:
1850 main.log.exception( self.name + ": Object not as expected" )
1851 return None
1852 except pexpect.EOF:
1853 main.log.error( self.name + ": EOF exception found" )
1854 main.log.error( self.name + ": " + self.handle.before )
1855 main.cleanup()
1856 main.exit()
1857 except Exception:
1858 main.log.exception( self.name + ": Uncaught exception!" )
1859 main.cleanup()
1860 main.exit()
1861
Jon Hallefbd9792015-03-05 16:11:36 -08001862 def removeIntent( self, intentId, app='org.onosproject.cli',
1863 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001864 """
shahshreya1c818fc2015-02-26 13:44:08 -08001865 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001866 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001867 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001868 -p or --purge: Purge the intent from the store after removal
1869
Jon Halle3f39ff2015-01-13 11:50:53 -08001870 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001871 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001873 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001874 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001875 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001876 if purge:
1877 cmdStr += " -p"
1878 if sync:
1879 cmdStr += " -s"
1880
1881 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001882 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001883 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001884 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001885 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001886 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001887 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001888 # TODO: Should this be main.TRUE
1889 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001890 except AssertionError:
1891 main.log.exception( "" )
1892 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001893 except TypeError:
1894 main.log.exception( self.name + ": Object not as expected" )
1895 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001896 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001897 main.log.error( self.name + ": EOF exception found" )
1898 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001899 main.cleanup()
1900 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001901 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001902 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001903 main.cleanup()
1904 main.exit()
1905
YPZhangfebf7302016-05-24 16:45:56 -07001906 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001907 """
1908 Description:
1909 Remove all the intents
1910 Optional args:-
1911 -s or --sync: Waits for the removal before returning
1912 -p or --purge: Purge the intent from the store after removal
1913 Returns:
1914 Returns main.TRUE if all intents are removed, otherwise returns
1915 main.FALSE; Returns None for exception
1916 """
1917 try:
1918 cmdStr = "remove-intent"
1919 if purge:
1920 cmdStr += " -p"
1921 if sync:
1922 cmdStr += " -s"
1923
1924 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001925 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001926 assert "Command not found:" not in handle, handle
1927 if re.search( "Error", handle ):
1928 main.log.error( "Error in removing intent" )
1929 return main.FALSE
1930 else:
1931 return main.TRUE
1932 except AssertionError:
1933 main.log.exception( "" )
1934 return None
1935 except TypeError:
1936 main.log.exception( self.name + ": Object not as expected" )
1937 return None
1938 except pexpect.EOF:
1939 main.log.error( self.name + ": EOF exception found" )
1940 main.log.error( self.name + ": " + self.handle.before )
1941 main.cleanup()
1942 main.exit()
1943 except Exception:
1944 main.log.exception( self.name + ": Uncaught exception!" )
1945 main.cleanup()
1946 main.exit()
1947
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001948 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001949 """
1950 Purges all WITHDRAWN Intents
1951 """
1952 try:
1953 cmdStr = "purge-intents"
1954 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001955 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001956 if re.search( "Error", handle ):
1957 main.log.error( "Error in purging intents" )
1958 return main.FALSE
1959 else:
1960 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001961 except AssertionError:
1962 main.log.exception( "" )
1963 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001964 except TypeError:
1965 main.log.exception( self.name + ": Object not as expected" )
1966 return None
1967 except pexpect.EOF:
1968 main.log.error( self.name + ": EOF exception found" )
1969 main.log.error( self.name + ": " + self.handle.before )
1970 main.cleanup()
1971 main.exit()
1972 except Exception:
1973 main.log.exception( self.name + ": Uncaught exception!" )
1974 main.cleanup()
1975 main.exit()
1976
kelvin-onlabd3b64892015-01-20 13:26:24 -08001977 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001978 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001979 NOTE: This method should be used after installing application:
1980 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001981 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001983 Description:
1984 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001985 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001986 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001987 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001988 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001989 cmdStr += " -j"
1990 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001991 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001992 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001993 except AssertionError:
1994 main.log.exception( "" )
1995 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001996 except TypeError:
1997 main.log.exception( self.name + ": Object not as expected" )
1998 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001999 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002000 main.log.error( self.name + ": EOF exception found" )
2001 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002002 main.cleanup()
2003 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002004 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002005 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002006 main.cleanup()
2007 main.exit()
2008
pingping-lin54b03372015-08-13 14:43:10 -07002009 def ipv4RouteNumber( self ):
2010 """
2011 NOTE: This method should be used after installing application:
2012 onos-app-sdnip
2013 Description:
2014 Obtain the total IPv4 routes number in the system
2015 """
2016 try:
2017 cmdStr = "routes -s -j"
2018 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002019 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002020 jsonResult = json.loads( handle )
2021 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002022 except AssertionError:
2023 main.log.exception( "" )
2024 return None
2025 except ( TypeError, ValueError ):
2026 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002027 return None
2028 except pexpect.EOF:
2029 main.log.error( self.name + ": EOF exception found" )
2030 main.log.error( self.name + ": " + self.handle.before )
2031 main.cleanup()
2032 main.exit()
2033 except Exception:
2034 main.log.exception( self.name + ": Uncaught exception!" )
2035 main.cleanup()
2036 main.exit()
2037
pingping-lin8244a3b2015-09-16 13:36:56 -07002038 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002039 """
andrewonlabe6745342014-10-17 14:29:13 -04002040 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002041 Obtain intents from the ONOS cli.
2042 Optional:
2043 * jsonFormat: Enable output formatting in json, default to True
2044 * summary: Whether only output the intent summary, defaults to False
2045 * type: Only output a certain type of intent. This options is valid
2046 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002047 """
andrewonlabe6745342014-10-17 14:29:13 -04002048 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002049 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002050 if summary:
2051 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002053 cmdStr += " -j"
2054 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002055 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002056 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002057 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002058 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002059 else:
Jon Hallff566d52016-01-15 14:45:36 -08002060 intentType = ""
2061 # IF we want the summary of a specific intent type
2062 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002063 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002064 if intentType in jsonResult.keys():
2065 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002066 else:
Jon Hallff566d52016-01-15 14:45:36 -08002067 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002068 return handle
2069 else:
2070 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002071 except AssertionError:
2072 main.log.exception( "" )
2073 return None
2074 except ( TypeError, ValueError ):
2075 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002076 return None
2077 except pexpect.EOF:
2078 main.log.error( self.name + ": EOF exception found" )
2079 main.log.error( self.name + ": " + self.handle.before )
2080 main.cleanup()
2081 main.exit()
2082 except Exception:
2083 main.log.exception( self.name + ": Uncaught exception!" )
2084 main.cleanup()
2085 main.exit()
2086
kelvin-onlab54400a92015-02-26 18:05:51 -08002087 def getIntentState(self, intentsId, intentsJson=None):
2088 """
You Wangfdcbfc42016-05-16 12:16:53 -07002089 Description:
2090 Gets intent state. Accepts a single intent ID (string type) or a
2091 list of intent IDs.
2092 Parameters:
2093 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002094 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002095 Returns:
2096 Returns the state (string type) of the ID if a single intent ID is
2097 accepted.
2098 Returns a list of dictionaries if a list of intent IDs is accepted,
2099 and each dictionary maps 'id' to the Intent ID and 'state' to
2100 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002101 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 try:
2103 state = "State is Undefined"
2104 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002105 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 else:
Jon Hallc6793552016-01-19 14:18:37 -08002107 rawJson = intentsJson
2108 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002109 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002110 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002111 if intentsId == intent[ 'id' ]:
2112 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002114 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2115 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002116 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002117 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002118 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002119 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002120 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002121 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002122 if intentsId[ i ] == intents[ 'id' ]:
2123 stateDict[ 'state' ] = intents[ 'state' ]
2124 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002125 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002126 break
Jon Hallefbd9792015-03-05 16:11:36 -08002127 if len( intentsId ) != len( dictList ):
2128 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002129 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002130 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002132 return None
Jon Hallc6793552016-01-19 14:18:37 -08002133 except ( TypeError, ValueError ):
2134 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002135 return None
2136 except pexpect.EOF:
2137 main.log.error( self.name + ": EOF exception found" )
2138 main.log.error( self.name + ": " + self.handle.before )
2139 main.cleanup()
2140 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002141 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002142 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002143 main.cleanup()
2144 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002145
kelvin-onlabf512e942015-06-08 19:42:59 -07002146 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002147 """
2148 Description:
2149 Check intents state
2150 Required:
2151 intentsId - List of intents ID to be checked
2152 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002153 expectedState - Check the expected state(s) of each intents
2154 state in the list.
2155 *NOTE: You can pass in a list of expected state,
2156 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002157 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002158 Returns main.TRUE only if all intent are the same as expected states
2159 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002160 """
2161 try:
2162 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002163 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002164 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002165 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002166 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002167 "getting intents state" )
2168 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002169
2170 if isinstance( expectedState, types.StringType ):
2171 for intents in intentsDict:
2172 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002173 main.log.debug( self.name + " : Intent ID - " +
2174 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002175 " actual state = " +
2176 intents.get( 'state' )
2177 + " does not equal expected state = "
2178 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002179 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002180
2181 elif isinstance( expectedState, types.ListType ):
2182 for intents in intentsDict:
2183 if not any( state == intents.get( 'state' ) for state in
2184 expectedState ):
2185 main.log.debug( self.name + " : Intent ID - " +
2186 intents.get( 'id' ) +
2187 " actual state = " +
2188 intents.get( 'state' ) +
2189 " does not equal expected states = "
2190 + str( expectedState ) )
2191 returnValue = main.FALSE
2192
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002193 if returnValue == main.TRUE:
2194 main.log.info( self.name + ": All " +
2195 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002196 " intents are in " + str( expectedState ) +
2197 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002198 return returnValue
2199 except TypeError:
2200 main.log.exception( self.name + ": Object not as expected" )
2201 return None
2202 except pexpect.EOF:
2203 main.log.error( self.name + ": EOF exception found" )
2204 main.log.error( self.name + ": " + self.handle.before )
2205 main.cleanup()
2206 main.exit()
2207 except Exception:
2208 main.log.exception( self.name + ": Uncaught exception!" )
2209 main.cleanup()
2210 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002211
You Wang66518af2016-05-16 15:32:59 -07002212 def compareIntent( self, intentDict ):
2213 """
2214 Description:
2215 Compare the intent ids and states provided in the argument with all intents in ONOS
2216 Return:
2217 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2218 Arguments:
2219 intentDict: a dictionary which maps intent ids to intent states
2220 """
2221 try:
2222 intentsRaw = self.intents()
2223 intentsJson = json.loads( intentsRaw )
2224 intentDictONOS = {}
2225 for intent in intentsJson:
2226 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002227 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002228 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002229 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002230 str( len( intentDict ) ) + " expected and " +
2231 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002232 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002233 for intentID in intentDict.keys():
2234 if not intentID in intentDictONOS.keys():
2235 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2236 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002237 else:
2238 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2239 main.log.debug( self.name + ": intent ID - " + intentID +
2240 " expected state is " + intentDict[ intentID ] +
2241 " but actual state is " + intentDictONOS[ intentID ] )
2242 returnValue = main.FALSE
2243 intentDictONOS.pop( intentID )
2244 if len( intentDictONOS ) > 0:
2245 returnValue = main.FALSE
2246 for intentID in intentDictONOS.keys():
2247 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002248 if returnValue == main.TRUE:
2249 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2250 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002251 except KeyError:
2252 main.log.exception( self.name + ": KeyError exception found" )
2253 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002254 except ( TypeError, ValueError ):
2255 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002256 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002257 except pexpect.EOF:
2258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
2260 main.cleanup()
2261 main.exit()
2262 except Exception:
2263 main.log.exception( self.name + ": Uncaught exception!" )
2264 main.cleanup()
2265 main.exit()
2266
YPZhang14a4aa92016-07-15 13:37:15 -07002267 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002268 """
2269 Description:
2270 Check the number of installed intents.
2271 Optional:
2272 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002273 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002274 Return:
2275 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2276 , otherwise, returns main.FALSE.
2277 """
2278
2279 try:
2280 cmd = "intents -s -j"
2281
2282 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002283 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002284 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002285 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002286 response = json.loads( response )
2287
2288 # get total and installed number, see if they are match
2289 allState = response.get( 'all' )
2290 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002291 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002292 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002293 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002294 return main.FALSE
2295
Jon Hallc6793552016-01-19 14:18:37 -08002296 except ( TypeError, ValueError ):
2297 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002298 return None
2299 except pexpect.EOF:
2300 main.log.error( self.name + ": EOF exception found" )
2301 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002302 if noExit:
2303 return main.FALSE
2304 else:
2305 main.cleanup()
2306 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002307 except Exception:
2308 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002309 if noExit:
2310 return main.FALSE
2311 else:
2312 main.cleanup()
2313 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002314 except pexpect.TIMEOUT:
2315 main.log.error( self.name + ": ONOS timeout" )
2316 return None
GlennRCed771242016-01-13 17:02:47 -08002317
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002318 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002319 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002320 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002322 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002323 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002324 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002325 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002326 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002327 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002328 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002329 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002330 if noCore:
2331 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002332 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002333 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002334 assert "Command not found:" not in handle, handle
2335 if re.search( "Error:", handle ):
2336 main.log.error( self.name + ": flows() response: " +
2337 str( handle ) )
2338 return handle
2339 except AssertionError:
2340 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002341 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
Jon Hallc6793552016-01-19 14:18:37 -08002345 except pexpect.TIMEOUT:
2346 main.log.error( self.name + ": ONOS timeout" )
2347 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002348 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002349 main.log.error( self.name + ": EOF exception found" )
2350 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002351 main.cleanup()
2352 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002353 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002354 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002355 main.cleanup()
2356 main.exit()
2357
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002358 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002359 count = self.getTotalFlowsNum( timeout=timeout )
2360 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002361 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002362
YPZhangebf9eb52016-05-12 15:20:24 -07002363 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002364 """
2365 Description:
GlennRCed771242016-01-13 17:02:47 -08002366 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002367 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2368 if the count of those states is 0, which means all current flows
2369 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002370 Optional:
GlennRCed771242016-01-13 17:02:47 -08002371 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002372 Return:
2373 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002374 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002375 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002376 """
2377 try:
GlennRCed771242016-01-13 17:02:47 -08002378 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2379 checkedStates = []
2380 statesCount = [0, 0, 0, 0]
2381 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002382 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002383 if rawFlows:
2384 # if we didn't get flows or flows function return None, we should return
2385 # main.Flase
2386 checkedStates.append( json.loads( rawFlows ) )
2387 else:
2388 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002389 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002390 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002391 try:
2392 statesCount[i] += int( c.get( "flowCount" ) )
2393 except TypeError:
2394 main.log.exception( "Json object not as expected" )
2395 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002396
GlennRCed771242016-01-13 17:02:47 -08002397 # We want to count PENDING_ADD if isPENDING is true
2398 if isPENDING:
2399 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2400 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002401 else:
GlennRCed771242016-01-13 17:02:47 -08002402 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2403 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002404 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002405 except ( TypeError, ValueError ):
2406 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002407 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002408
YPZhang240842b2016-05-17 12:00:50 -07002409 except AssertionError:
2410 main.log.exception( "" )
2411 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002412 except pexpect.EOF:
2413 main.log.error( self.name + ": EOF exception found" )
2414 main.log.error( self.name + ": " + self.handle.before )
2415 main.cleanup()
2416 main.exit()
2417 except Exception:
2418 main.log.exception( self.name + ": Uncaught exception!" )
2419 main.cleanup()
2420 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002421 except pexpect.TIMEOUT:
2422 main.log.error( self.name + ": ONOS timeout" )
2423 return None
2424
kelvin-onlab4df89f22015-04-13 18:10:23 -07002425
GlennRCed771242016-01-13 17:02:47 -08002426 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002427 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002428 """
andrewonlab87852b02014-11-19 18:44:19 -05002429 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002430 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002431 a specific point-to-point intent definition
2432 Required:
GlennRCed771242016-01-13 17:02:47 -08002433 * ingress: specify source dpid
2434 * egress: specify destination dpid
2435 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002436 Optional:
GlennRCed771242016-01-13 17:02:47 -08002437 * offset: the keyOffset is where the next batch of intents
2438 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002439 * noExit: If set to True, TestON will not exit if any error when issus command
2440 * getResponse: If set to True, function will return ONOS response.
2441
GlennRCed771242016-01-13 17:02:47 -08002442 Returns: If failed to push test intents, it will returen None,
2443 if successful, return true.
2444 Timeout expection will return None,
2445 TypeError will return false
2446 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002447 """
andrewonlab87852b02014-11-19 18:44:19 -05002448 try:
GlennRCed771242016-01-13 17:02:47 -08002449 if background:
2450 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002451 else:
GlennRCed771242016-01-13 17:02:47 -08002452 back = ""
2453 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002454 ingress,
2455 egress,
2456 batchSize,
2457 offset,
2458 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002459 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002460 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002461 main.log.info( response )
2462 if response == None:
2463 return None
2464
YPZhangb34b7e12016-06-14 14:28:19 -07002465 if getResponse:
2466 return response
2467
GlennRCed771242016-01-13 17:02:47 -08002468 # TODO: We should handle if there is failure in installation
2469 return main.TRUE
2470
Jon Hallc6793552016-01-19 14:18:37 -08002471 except AssertionError:
2472 main.log.exception( "" )
2473 return None
GlennRCed771242016-01-13 17:02:47 -08002474 except pexpect.TIMEOUT:
2475 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002476 return None
andrewonlab87852b02014-11-19 18:44:19 -05002477 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002478 main.log.error( self.name + ": EOF exception found" )
2479 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002480 main.cleanup()
2481 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002482 except TypeError:
2483 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002484 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002485 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002486 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002487 main.cleanup()
2488 main.exit()
2489
YPZhangebf9eb52016-05-12 15:20:24 -07002490 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002491 """
2492 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002493 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002494 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002495 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002496 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002497 """
YPZhange3109a72016-02-02 11:25:37 -08002498
YPZhangb5d3f832016-01-23 22:54:26 -08002499 try:
YPZhange3109a72016-02-02 11:25:37 -08002500 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002501 cmd = "flows -c added"
2502 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2503 if rawFlows:
2504 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002505 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002506 for l in rawFlows:
2507 totalFlows += int(l.split("Count=")[1])
2508 else:
2509 main.log.error("Response not as expected!")
2510 return None
2511 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002512
You Wangd3cb2ce2016-05-16 14:01:24 -07002513 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002514 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002515 return None
2516 except pexpect.EOF:
2517 main.log.error( self.name + ": EOF exception found" )
2518 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002519 if not noExit:
2520 main.cleanup()
2521 main.exit()
2522 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002523 except Exception:
2524 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002525 if not noExit:
2526 main.cleanup()
2527 main.exit()
2528 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002529 except pexpect.TIMEOUT:
2530 main.log.error( self.name + ": ONOS timeout" )
2531 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002532
YPZhang14a4aa92016-07-15 13:37:15 -07002533 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002534 """
2535 Description:
2536 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002537 Optional:
2538 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002539 Return:
2540 The number of intents
2541 """
2542 try:
2543 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002544 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002545 if response == None:
2546 return -1
2547 response = json.loads( response )
2548 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002549 except ( TypeError, ValueError ):
2550 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002551 return None
2552 except pexpect.EOF:
2553 main.log.error( self.name + ": EOF exception found" )
2554 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002555 if noExit:
2556 return -1
2557 else:
2558 main.cleanup()
2559 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002560 except Exception:
2561 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002562 if noExit:
2563 return -1
2564 else:
2565 main.cleanup()
2566 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002567
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002569 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002570 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002571 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002573 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002574 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002575 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002576 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002577 cmdStr += " -j"
2578 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002579 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002580 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002581 except AssertionError:
2582 main.log.exception( "" )
2583 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002584 except TypeError:
2585 main.log.exception( self.name + ": Object not as expected" )
2586 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002588 main.log.error( self.name + ": EOF exception found" )
2589 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002590 main.cleanup()
2591 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002592 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002593 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002594 main.cleanup()
2595 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002596
kelvin-onlabd3b64892015-01-20 13:26:24 -08002597 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002598 """
2599 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002600 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002602 """
andrewonlab867212a2014-10-22 20:13:38 -04002603 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002604 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002605 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002606 cmdStr += " -j"
2607 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002608 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002609 if handle:
2610 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002611 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002612 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002613 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002614 else:
2615 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002616 except AssertionError:
2617 main.log.exception( "" )
2618 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002619 except TypeError:
2620 main.log.exception( self.name + ": Object not as expected" )
2621 return None
andrewonlab867212a2014-10-22 20:13:38 -04002622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002623 main.log.error( self.name + ": EOF exception found" )
2624 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002625 main.cleanup()
2626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002627 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002628 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002629 main.cleanup()
2630 main.exit()
2631
kelvin8ec71442015-01-15 16:57:00 -08002632 # Wrapper functions ****************
2633 # Wrapper functions use existing driver
2634 # functions and extends their use case.
2635 # For example, we may use the output of
2636 # a normal driver function, and parse it
2637 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002638
kelvin-onlabd3b64892015-01-20 13:26:24 -08002639 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002640 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002641 Description:
2642 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002643 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002644 try:
kelvin8ec71442015-01-15 16:57:00 -08002645 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002646 intentsStr = self.intents(jsonFormat=True)
2647 # Convert to a dictionary
2648 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002649 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002650 for intent in intents:
2651 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002652 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002653 except TypeError:
2654 main.log.exception( self.name + ": Object not as expected" )
2655 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002656 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002657 main.log.error( self.name + ": EOF exception found" )
2658 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002659 main.cleanup()
2660 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002661 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002662 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002663 main.cleanup()
2664 main.exit()
2665
You Wang3c276252016-09-21 15:21:36 -07002666 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002667 """
2668 Determine the number of flow rules for the given device id that are
2669 in the added state
You Wang3c276252016-09-21 15:21:36 -07002670 Params:
2671 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002672 """
2673 try:
You Wang3c276252016-09-21 15:21:36 -07002674 if core:
2675 cmdStr = "flows any " + str( deviceId ) + " | " +\
2676 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2677 else:
2678 cmdStr = "flows any " + str( deviceId ) + " | " +\
2679 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002680 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002681 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002682 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002683 except AssertionError:
2684 main.log.exception( "" )
2685 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002686 except pexpect.EOF:
2687 main.log.error( self.name + ": EOF exception found" )
2688 main.log.error( self.name + ": " + self.handle.before )
2689 main.cleanup()
2690 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002691 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002692 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002693 main.cleanup()
2694 main.exit()
2695
kelvin-onlabd3b64892015-01-20 13:26:24 -08002696 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002697 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002698 Use 'devices' function to obtain list of all devices
2699 and parse the result to obtain a list of all device
2700 id's. Returns this list. Returns empty list if no
2701 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002702 List is ordered sequentially
2703
andrewonlab3e15ead2014-10-15 14:21:34 -04002704 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002705 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002706 the ids. By obtaining the list of device ids on the fly,
2707 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002708 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002709 try:
kelvin8ec71442015-01-15 16:57:00 -08002710 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002711 devicesStr = self.devices( jsonFormat=False )
2712 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002713
kelvin-onlabd3b64892015-01-20 13:26:24 -08002714 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002715 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 return idList
kelvin8ec71442015-01-15 16:57:00 -08002717
2718 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002719 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002720 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002722 # Split list further into arguments before and after string
2723 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002724 # append to idList
2725 for arg in tempList:
2726 idList.append( arg.split( "id=" )[ 1 ] )
2727 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002728
Jon Halld4d4b372015-01-28 16:02:41 -08002729 except TypeError:
2730 main.log.exception( self.name + ": Object not as expected" )
2731 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002735 main.cleanup()
2736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002737 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002738 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002739 main.cleanup()
2740 main.exit()
2741
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002743 """
andrewonlab7c211572014-10-15 16:45:20 -04002744 Uses 'nodes' function to obtain list of all nodes
2745 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002746 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002747 Returns:
2748 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002749 """
andrewonlab7c211572014-10-15 16:45:20 -04002750 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002751 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002752 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002753 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002754 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002756 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002758 nodesJson = json.loads( nodesStr )
2759 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002760 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002761 except ( TypeError, ValueError ):
2762 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002763 return None
andrewonlab7c211572014-10-15 16:45:20 -04002764 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002765 main.log.error( self.name + ": EOF exception found" )
2766 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002767 main.cleanup()
2768 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002769 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002770 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002771 main.cleanup()
2772 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002773
kelvin-onlabd3b64892015-01-20 13:26:24 -08002774 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002775 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002776 Return the first device from the devices api whose 'id' contains 'dpid'
2777 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002778 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002779 try:
kelvin8ec71442015-01-15 16:57:00 -08002780 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002781 return None
2782 else:
kelvin8ec71442015-01-15 16:57:00 -08002783 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002784 rawDevices = self.devices()
2785 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002786 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002787 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002788 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2789 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002790 return device
2791 return None
Jon Hallc6793552016-01-19 14:18:37 -08002792 except ( TypeError, ValueError ):
2793 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002794 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002795 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002796 main.log.error( self.name + ": EOF exception found" )
2797 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002798 main.cleanup()
2799 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002800 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002801 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002802 main.cleanup()
2803 main.exit()
2804
You Wang24139872016-05-03 11:48:47 -07002805 def getTopology( self, topologyOutput ):
2806 """
2807 Definition:
2808 Loads a json topology output
2809 Return:
2810 topology = current ONOS topology
2811 """
2812 import json
2813 try:
2814 # either onos:topology or 'topology' will work in CLI
2815 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002816 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002817 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002818 except ( TypeError, ValueError ):
2819 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2820 return None
You Wang24139872016-05-03 11:48:47 -07002821 except pexpect.EOF:
2822 main.log.error( self.name + ": EOF exception found" )
2823 main.log.error( self.name + ": " + self.handle.before )
2824 main.cleanup()
2825 main.exit()
2826 except Exception:
2827 main.log.exception( self.name + ": Uncaught exception!" )
2828 main.cleanup()
2829 main.exit()
2830
Flavio Castro82ee2f62016-06-07 15:04:12 -07002831 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002832 """
Jon Hallefbd9792015-03-05 16:11:36 -08002833 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002834 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002835 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002836
Flavio Castro82ee2f62016-06-07 15:04:12 -07002837 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002838 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002839 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002840 logLevel = level to log to.
2841 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002842
Jon Hallefbd9792015-03-05 16:11:36 -08002843 Returns: main.TRUE if the number of switches and links are correct,
2844 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002845 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002846 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002847 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002848 try:
You Wang13310252016-07-31 10:56:14 -07002849 summary = self.summary()
2850 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002851 except ( TypeError, ValueError ):
2852 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2853 return main.ERROR
2854 try:
2855 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002856 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002857 return main.ERROR
2858 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002859 # Is the number of switches is what we expected
2860 devices = topology.get( 'devices', False )
2861 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002862 nodes = summary.get( 'nodes', False )
2863 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002864 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002865 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002866 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002868 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2869 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002870 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002871 output = output + "The number of links and switches match "\
2872 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002873 result = main.TRUE
2874 else:
You Wang24139872016-05-03 11:48:47 -07002875 output = output + \
2876 "The number of links and switches does not match " + \
2877 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002878 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002879 output = output + "\n ONOS sees %i devices" % int( devices )
2880 output = output + " (%i expected) " % int( numoswitch )
2881 output = output + "and %i links " % int( links )
2882 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002883 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002884 output = output + "and %i controllers " % int( nodes )
2885 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002886 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002887 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002889 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002890 else:
You Wang24139872016-05-03 11:48:47 -07002891 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002892 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002894 main.log.error( self.name + ": EOF exception found" )
2895 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002896 main.cleanup()
2897 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002899 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002900 main.cleanup()
2901 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002902
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002904 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002905 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002906 deviceId must be the id of a device as seen in the onos devices command
2907 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002908 role must be either master, standby, or none
2909
Jon Halle3f39ff2015-01-13 11:50:53 -08002910 Returns:
2911 main.TRUE or main.FALSE based on argument verification and
2912 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002913 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002914 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002915 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002916 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 cmdStr = "device-role " +\
2918 str( deviceId ) + " " +\
2919 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002920 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002922 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002923 if re.search( "Error", handle ):
2924 # end color output to escape any colours
2925 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002926 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002927 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002928 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002929 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002930 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002931 main.log.error( "Invalid 'role' given to device_role(). " +
2932 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002933 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002934 except AssertionError:
2935 main.log.exception( "" )
2936 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002937 except TypeError:
2938 main.log.exception( self.name + ": Object not as expected" )
2939 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002940 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002941 main.log.error( self.name + ": EOF exception found" )
2942 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002943 main.cleanup()
2944 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002945 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002946 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002947 main.cleanup()
2948 main.exit()
2949
kelvin-onlabd3b64892015-01-20 13:26:24 -08002950 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002951 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002952 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002953 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002954 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002955 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002956 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002957 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002958 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002959 cmdStr += " -j"
2960 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002961 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002962 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002963 except AssertionError:
2964 main.log.exception( "" )
2965 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002966 except TypeError:
2967 main.log.exception( self.name + ": Object not as expected" )
2968 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002969 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002970 main.log.error( self.name + ": EOF exception found" )
2971 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002972 main.cleanup()
2973 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002974 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002975 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002976 main.cleanup()
2977 main.exit()
2978
kelvin-onlabd3b64892015-01-20 13:26:24 -08002979 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002980 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002981 CLI command to get the current leader for the Election test application
2982 NOTE: Requires installation of the onos-app-election feature
2983 Returns: Node IP of the leader if one exists
2984 None if none exists
2985 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002986 """
Jon Hall94fd0472014-12-08 11:52:42 -08002987 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002988 cmdStr = "election-test-leader"
2989 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002990 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002991 # Leader
2992 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002993 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002994 nodeSearch = re.search( leaderPattern, response )
2995 if nodeSearch:
2996 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002997 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002998 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002999 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003000 # no leader
3001 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003002 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003003 nullSearch = re.search( nullPattern, response )
3004 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003006 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003007 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003009 main.log.error( "Error in electionTestLeader on " + self.name +
3010 ": " + "unexpected response" )
3011 main.log.error( repr( response ) )
3012 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003013 except AssertionError:
3014 main.log.exception( "" )
3015 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003016 except TypeError:
3017 main.log.exception( self.name + ": Object not as expected" )
3018 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003020 main.log.error( self.name + ": EOF exception found" )
3021 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003022 main.cleanup()
3023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003025 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003026 main.cleanup()
3027 main.exit()
3028
kelvin-onlabd3b64892015-01-20 13:26:24 -08003029 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003030 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003031 CLI command to run for leadership of the Election test application.
3032 NOTE: Requires installation of the onos-app-election feature
3033 Returns: Main.TRUE on success
3034 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003035 """
Jon Hall94fd0472014-12-08 11:52:42 -08003036 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 cmdStr = "election-test-run"
3038 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003039 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003041 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003042 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003043 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003044 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003045 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003046 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003047 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003048 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003049 main.log.error( "Error in electionTestRun on " + self.name +
3050 ": " + "unexpected response" )
3051 main.log.error( repr( response ) )
3052 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003053 except AssertionError:
3054 main.log.exception( "" )
3055 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003056 except TypeError:
3057 main.log.exception( self.name + ": Object not as expected" )
3058 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003059 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003060 main.log.error( self.name + ": EOF exception found" )
3061 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003062 main.cleanup()
3063 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003064 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003065 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003066 main.cleanup()
3067 main.exit()
3068
kelvin-onlabd3b64892015-01-20 13:26:24 -08003069 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003070 """
Jon Hall94fd0472014-12-08 11:52:42 -08003071 * CLI command to withdraw the local node from leadership election for
3072 * the Election test application.
3073 #NOTE: Requires installation of the onos-app-election feature
3074 Returns: Main.TRUE on success
3075 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003076 """
Jon Hall94fd0472014-12-08 11:52:42 -08003077 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003078 cmdStr = "election-test-withdraw"
3079 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003080 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003081 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003082 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003083 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003084 if re.search( successPattern, response ):
3085 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003086 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003087 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003088 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003089 main.log.error( "Error in electionTestWithdraw on " +
3090 self.name + ": " + "unexpected response" )
3091 main.log.error( repr( response ) )
3092 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003093 except AssertionError:
3094 main.log.exception( "" )
3095 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003096 except TypeError:
3097 main.log.exception( self.name + ": Object not as expected" )
3098 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003102 main.cleanup()
3103 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003105 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003106 main.cleanup()
3107 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003108
kelvin8ec71442015-01-15 16:57:00 -08003109 def getDevicePortsEnabledCount( self, dpid ):
3110 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003111 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003112 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003113 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003114 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003115 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3116 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003117 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003118 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003119 if re.search( "No such device", output ):
3120 main.log.error( "Error in getting ports" )
3121 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003122 return output
Jon Hallc6793552016-01-19 14:18:37 -08003123 except AssertionError:
3124 main.log.exception( "" )
3125 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003126 except TypeError:
3127 main.log.exception( self.name + ": Object not as expected" )
3128 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003130 main.log.error( self.name + ": EOF exception found" )
3131 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003132 main.cleanup()
3133 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003134 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003135 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003136 main.cleanup()
3137 main.exit()
3138
kelvin8ec71442015-01-15 16:57:00 -08003139 def getDeviceLinksActiveCount( self, dpid ):
3140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003142 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003144 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003145 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3146 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003147 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003148 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003149 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003150 main.log.error( "Error in getting ports " )
3151 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003152 return output
Jon Hallc6793552016-01-19 14:18:37 -08003153 except AssertionError:
3154 main.log.exception( "" )
3155 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003156 except TypeError:
3157 main.log.exception( self.name + ": Object not as expected" )
3158 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003160 main.log.error( self.name + ": EOF exception found" )
3161 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003162 main.cleanup()
3163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003165 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003166 main.cleanup()
3167 main.exit()
3168
kelvin8ec71442015-01-15 16:57:00 -08003169 def getAllIntentIds( self ):
3170 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003171 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003172 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003173 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003174 cmdStr = "onos:intents | grep id="
3175 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003176 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003177 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003178 if re.search( "Error", output ):
3179 main.log.error( "Error in getting ports" )
3180 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003181 return output
Jon Hallc6793552016-01-19 14:18:37 -08003182 except AssertionError:
3183 main.log.exception( "" )
3184 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003185 except TypeError:
3186 main.log.exception( self.name + ": Object not as expected" )
3187 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003188 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003189 main.log.error( self.name + ": EOF exception found" )
3190 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003191 main.cleanup()
3192 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003193 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003194 main.log.exception( self.name + ": Uncaught exception!" )
3195 main.cleanup()
3196 main.exit()
3197
Jon Hall73509952015-02-24 16:42:56 -08003198 def intentSummary( self ):
3199 """
Jon Hallefbd9792015-03-05 16:11:36 -08003200 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003201 """
3202 try:
3203 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003204 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003205 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003206 states.append( intent.get( 'state', None ) )
3207 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003208 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003209 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003210 except ( TypeError, ValueError ):
3211 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003212 return None
3213 except pexpect.EOF:
3214 main.log.error( self.name + ": EOF exception found" )
3215 main.log.error( self.name + ": " + self.handle.before )
3216 main.cleanup()
3217 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003218 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003219 main.log.exception( self.name + ": Uncaught exception!" )
3220 main.cleanup()
3221 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003222
Jon Hall61282e32015-03-19 11:34:11 -07003223 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003224 """
3225 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003226 Optional argument:
3227 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003228 """
Jon Hall63604932015-02-26 17:09:50 -08003229 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003230 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003231 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003232 cmdStr += " -j"
3233 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003234 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003235 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003236 return output
Jon Hallc6793552016-01-19 14:18:37 -08003237 except AssertionError:
3238 main.log.exception( "" )
3239 return None
Jon Hall63604932015-02-26 17:09:50 -08003240 except TypeError:
3241 main.log.exception( self.name + ": Object not as expected" )
3242 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003243 except pexpect.EOF:
3244 main.log.error( self.name + ": EOF exception found" )
3245 main.log.error( self.name + ": " + self.handle.before )
3246 main.cleanup()
3247 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003248 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003249 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003250 main.cleanup()
3251 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003252
acsmarsa4a4d1e2015-07-10 16:01:24 -07003253 def leaderCandidates( self, jsonFormat=True ):
3254 """
3255 Returns the output of the leaders -c command.
3256 Optional argument:
3257 * jsonFormat - boolean indicating if you want output in json
3258 """
3259 try:
3260 cmdStr = "onos:leaders -c"
3261 if jsonFormat:
3262 cmdStr += " -j"
3263 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003264 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003265 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003266 return output
Jon Hallc6793552016-01-19 14:18:37 -08003267 except AssertionError:
3268 main.log.exception( "" )
3269 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003270 except TypeError:
3271 main.log.exception( self.name + ": Object not as expected" )
3272 return None
3273 except pexpect.EOF:
3274 main.log.error( self.name + ": EOF exception found" )
3275 main.log.error( self.name + ": " + self.handle.before )
3276 main.cleanup()
3277 main.exit()
3278 except Exception:
3279 main.log.exception( self.name + ": Uncaught exception!" )
3280 main.cleanup()
3281 main.exit()
3282
Jon Hallc6793552016-01-19 14:18:37 -08003283 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003284 """
3285 Returns a list in format [leader,candidate1,candidate2,...] for a given
3286 topic parameter and an empty list if the topic doesn't exist
3287 If no leader is elected leader in the returned list will be "none"
3288 Returns None if there is a type error processing the json object
3289 """
3290 try:
Jon Hall6e709752016-02-01 13:38:46 -08003291 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003292 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003293 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003294 assert "Command not found:" not in rawOutput, rawOutput
3295 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003296 results = []
3297 for dict in output:
3298 if dict["topic"] == topic:
3299 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003300 candidates = re.split( ", ", dict["candidates"][1:-1] )
3301 results.append( leader )
3302 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003303 return results
Jon Hallc6793552016-01-19 14:18:37 -08003304 except AssertionError:
3305 main.log.exception( "" )
3306 return None
3307 except ( TypeError, ValueError ):
3308 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003309 return None
3310 except pexpect.EOF:
3311 main.log.error( self.name + ": EOF exception found" )
3312 main.log.error( self.name + ": " + self.handle.before )
3313 main.cleanup()
3314 main.exit()
3315 except Exception:
3316 main.log.exception( self.name + ": Uncaught exception!" )
3317 main.cleanup()
3318 main.exit()
3319
Jon Hall61282e32015-03-19 11:34:11 -07003320 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003321 """
3322 Returns the output of the intent Pending map.
3323 """
Jon Hall63604932015-02-26 17:09:50 -08003324 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003325 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003326 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003327 cmdStr += " -j"
3328 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003329 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003330 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003331 return output
Jon Hallc6793552016-01-19 14:18:37 -08003332 except AssertionError:
3333 main.log.exception( "" )
3334 return None
Jon Hall63604932015-02-26 17:09:50 -08003335 except TypeError:
3336 main.log.exception( self.name + ": Object not as expected" )
3337 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()
Jon Hall77ba41c2015-04-06 10:25:40 -07003343 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003344 main.log.exception( self.name + ": Uncaught exception!" )
3345 main.cleanup()
3346 main.exit()
3347
Jon Hall2c8959e2016-12-16 12:17:34 -08003348 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003349 """
3350 Returns the output of the raft partitions command for ONOS.
3351 """
Jon Hall61282e32015-03-19 11:34:11 -07003352 # Sample JSON
3353 # {
3354 # "leader": "tcp://10.128.30.11:7238",
3355 # "members": [
3356 # "tcp://10.128.30.11:7238",
3357 # "tcp://10.128.30.17:7238",
3358 # "tcp://10.128.30.13:7238",
3359 # ],
3360 # "name": "p1",
3361 # "term": 3
3362 # },
Jon Hall63604932015-02-26 17:09:50 -08003363 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003364 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003365 if candidates:
3366 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003367 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003368 cmdStr += " -j"
3369 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003370 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003371 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003372 return output
Jon Hallc6793552016-01-19 14:18:37 -08003373 except AssertionError:
3374 main.log.exception( "" )
3375 return None
Jon Hall63604932015-02-26 17:09:50 -08003376 except TypeError:
3377 main.log.exception( self.name + ": Object not as expected" )
3378 return None
3379 except pexpect.EOF:
3380 main.log.error( self.name + ": EOF exception found" )
3381 main.log.error( self.name + ": " + self.handle.before )
3382 main.cleanup()
3383 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003384 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003385 main.log.exception( self.name + ": Uncaught exception!" )
3386 main.cleanup()
3387 main.exit()
3388
Jon Halle9f909e2016-09-23 10:43:12 -07003389 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003390 """
3391 Returns the output of the apps command for ONOS. This command lists
3392 information about installed ONOS applications
3393 """
3394 # Sample JSON object
3395 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3396 # "description":"ONOS OpenFlow protocol southbound providers",
3397 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3398 # "features":"[onos-openflow]","state":"ACTIVE"}]
3399 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003400 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003401 if summary:
3402 cmdStr += " -s"
3403 if active:
3404 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003405 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003406 cmdStr += " -j"
3407 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003408 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003409 assert "Command not found:" not in output, output
3410 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003411 return output
Jon Hallbe379602015-03-24 13:39:32 -07003412 # FIXME: look at specific exceptions/Errors
3413 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003414 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003415 return None
3416 except TypeError:
3417 main.log.exception( self.name + ": Object not as expected" )
3418 return None
3419 except pexpect.EOF:
3420 main.log.error( self.name + ": EOF exception found" )
3421 main.log.error( self.name + ": " + self.handle.before )
3422 main.cleanup()
3423 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003424 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003425 main.log.exception( self.name + ": Uncaught exception!" )
3426 main.cleanup()
3427 main.exit()
3428
Jon Hall146f1522015-03-24 15:33:24 -07003429 def appStatus( self, appName ):
3430 """
3431 Uses the onos:apps cli command to return the status of an application.
3432 Returns:
3433 "ACTIVE" - If app is installed and activated
3434 "INSTALLED" - If app is installed and deactivated
3435 "UNINSTALLED" - If app is not installed
3436 None - on error
3437 """
Jon Hall146f1522015-03-24 15:33:24 -07003438 try:
3439 if not isinstance( appName, types.StringType ):
3440 main.log.error( self.name + ".appStatus(): appName must be" +
3441 " a string" )
3442 return None
3443 output = self.apps( jsonFormat=True )
3444 appsJson = json.loads( output )
3445 state = None
3446 for app in appsJson:
3447 if appName == app.get('name'):
3448 state = app.get('state')
3449 break
3450 if state == "ACTIVE" or state == "INSTALLED":
3451 return state
3452 elif state is None:
3453 return "UNINSTALLED"
3454 elif state:
3455 main.log.error( "Unexpected state from 'onos:apps': " +
3456 str( state ) )
3457 return state
Jon Hallc6793552016-01-19 14:18:37 -08003458 except ( TypeError, ValueError ):
3459 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003460 return None
3461 except pexpect.EOF:
3462 main.log.error( self.name + ": EOF exception found" )
3463 main.log.error( self.name + ": " + self.handle.before )
3464 main.cleanup()
3465 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003466 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003467 main.log.exception( self.name + ": Uncaught exception!" )
3468 main.cleanup()
3469 main.exit()
3470
Jon Hallbe379602015-03-24 13:39:32 -07003471 def app( self, appName, option ):
3472 """
3473 Interacts with the app command for ONOS. This command manages
3474 application inventory.
3475 """
Jon Hallbe379602015-03-24 13:39:32 -07003476 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003477 # Validate argument types
3478 valid = True
3479 if not isinstance( appName, types.StringType ):
3480 main.log.error( self.name + ".app(): appName must be a " +
3481 "string" )
3482 valid = False
3483 if not isinstance( option, types.StringType ):
3484 main.log.error( self.name + ".app(): option must be a string" )
3485 valid = False
3486 if not valid:
3487 return main.FALSE
3488 # Validate Option
3489 option = option.lower()
3490 # NOTE: Install may become a valid option
3491 if option == "activate":
3492 pass
3493 elif option == "deactivate":
3494 pass
3495 elif option == "uninstall":
3496 pass
3497 else:
3498 # Invalid option
3499 main.log.error( "The ONOS app command argument only takes " +
3500 "the values: (activate|deactivate|uninstall)" +
3501 "; was given '" + option + "'")
3502 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003503 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003504 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003505 if "Error executing command" in output:
3506 main.log.error( "Error in processing onos:app command: " +
3507 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003508 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003509 elif "No such application" in output:
3510 main.log.error( "The application '" + appName +
3511 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003512 return main.FALSE
3513 elif "Command not found:" in output:
3514 main.log.error( "Error in processing onos:app command: " +
3515 str( output ) )
3516 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003517 elif "Unsupported command:" in output:
3518 main.log.error( "Incorrect command given to 'app': " +
3519 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003520 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003521 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003522 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003523 return main.TRUE
3524 except TypeError:
3525 main.log.exception( self.name + ": Object not as expected" )
3526 return main.ERROR
3527 except pexpect.EOF:
3528 main.log.error( self.name + ": EOF exception found" )
3529 main.log.error( self.name + ": " + self.handle.before )
3530 main.cleanup()
3531 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003532 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003533 main.log.exception( self.name + ": Uncaught exception!" )
3534 main.cleanup()
3535 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003536
Jon Hallbd16b922015-03-26 17:53:15 -07003537 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003538 """
3539 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003540 appName is the hierarchical app name, not the feature name
3541 If check is True, method will check the status of the app after the
3542 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003543 Returns main.TRUE if the command was successfully sent
3544 main.FALSE if the cli responded with an error or given
3545 incorrect input
3546 """
3547 try:
3548 if not isinstance( appName, types.StringType ):
3549 main.log.error( self.name + ".activateApp(): appName must be" +
3550 " a string" )
3551 return main.FALSE
3552 status = self.appStatus( appName )
3553 if status == "INSTALLED":
3554 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003555 if check and response == main.TRUE:
3556 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003557 status = self.appStatus( appName )
3558 if status == "ACTIVE":
3559 return main.TRUE
3560 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003561 main.log.debug( "The state of application " +
3562 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003563 time.sleep( 1 )
3564 return main.FALSE
3565 else: # not 'check' or command didn't succeed
3566 return response
Jon Hall146f1522015-03-24 15:33:24 -07003567 elif status == "ACTIVE":
3568 return main.TRUE
3569 elif status == "UNINSTALLED":
3570 main.log.error( self.name + ": Tried to activate the " +
3571 "application '" + appName + "' which is not " +
3572 "installed." )
3573 else:
3574 main.log.error( "Unexpected return value from appStatus: " +
3575 str( status ) )
3576 return main.ERROR
3577 except TypeError:
3578 main.log.exception( self.name + ": Object not as expected" )
3579 return main.ERROR
3580 except pexpect.EOF:
3581 main.log.error( self.name + ": EOF exception found" )
3582 main.log.error( self.name + ": " + self.handle.before )
3583 main.cleanup()
3584 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003585 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003586 main.log.exception( self.name + ": Uncaught exception!" )
3587 main.cleanup()
3588 main.exit()
3589
Jon Hallbd16b922015-03-26 17:53:15 -07003590 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003591 """
3592 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003593 appName is the hierarchical app name, not the feature name
3594 If check is True, method will check the status of the app after the
3595 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003596 Returns main.TRUE if the command was successfully sent
3597 main.FALSE if the cli responded with an error or given
3598 incorrect input
3599 """
3600 try:
3601 if not isinstance( appName, types.StringType ):
3602 main.log.error( self.name + ".deactivateApp(): appName must " +
3603 "be a string" )
3604 return main.FALSE
3605 status = self.appStatus( appName )
3606 if status == "INSTALLED":
3607 return main.TRUE
3608 elif status == "ACTIVE":
3609 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003610 if check and response == main.TRUE:
3611 for i in range(10): # try 10 times then give up
3612 status = self.appStatus( appName )
3613 if status == "INSTALLED":
3614 return main.TRUE
3615 else:
3616 time.sleep( 1 )
3617 return main.FALSE
3618 else: # not check or command didn't succeed
3619 return response
Jon Hall146f1522015-03-24 15:33:24 -07003620 elif status == "UNINSTALLED":
3621 main.log.warn( self.name + ": Tried to deactivate the " +
3622 "application '" + appName + "' which is not " +
3623 "installed." )
3624 return main.TRUE
3625 else:
3626 main.log.error( "Unexpected return value from appStatus: " +
3627 str( status ) )
3628 return main.ERROR
3629 except TypeError:
3630 main.log.exception( self.name + ": Object not as expected" )
3631 return main.ERROR
3632 except pexpect.EOF:
3633 main.log.error( self.name + ": EOF exception found" )
3634 main.log.error( self.name + ": " + self.handle.before )
3635 main.cleanup()
3636 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003637 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003638 main.log.exception( self.name + ": Uncaught exception!" )
3639 main.cleanup()
3640 main.exit()
3641
Jon Hallbd16b922015-03-26 17:53:15 -07003642 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003643 """
3644 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003645 appName is the hierarchical app name, not the feature name
3646 If check is True, method will check the status of the app after the
3647 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003648 Returns main.TRUE if the command was successfully sent
3649 main.FALSE if the cli responded with an error or given
3650 incorrect input
3651 """
3652 # TODO: check with Thomas about the state machine for apps
3653 try:
3654 if not isinstance( appName, types.StringType ):
3655 main.log.error( self.name + ".uninstallApp(): appName must " +
3656 "be a string" )
3657 return main.FALSE
3658 status = self.appStatus( appName )
3659 if status == "INSTALLED":
3660 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003661 if check and response == main.TRUE:
3662 for i in range(10): # try 10 times then give up
3663 status = self.appStatus( appName )
3664 if status == "UNINSTALLED":
3665 return main.TRUE
3666 else:
3667 time.sleep( 1 )
3668 return main.FALSE
3669 else: # not check or command didn't succeed
3670 return response
Jon Hall146f1522015-03-24 15:33:24 -07003671 elif status == "ACTIVE":
3672 main.log.warn( self.name + ": Tried to uninstall the " +
3673 "application '" + appName + "' which is " +
3674 "currently active." )
3675 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003676 if check and response == main.TRUE:
3677 for i in range(10): # try 10 times then give up
3678 status = self.appStatus( appName )
3679 if status == "UNINSTALLED":
3680 return main.TRUE
3681 else:
3682 time.sleep( 1 )
3683 return main.FALSE
3684 else: # not check or command didn't succeed
3685 return response
Jon Hall146f1522015-03-24 15:33:24 -07003686 elif status == "UNINSTALLED":
3687 return main.TRUE
3688 else:
3689 main.log.error( "Unexpected return value from appStatus: " +
3690 str( status ) )
3691 return main.ERROR
3692 except TypeError:
3693 main.log.exception( self.name + ": Object not as expected" )
3694 return main.ERROR
3695 except pexpect.EOF:
3696 main.log.error( self.name + ": EOF exception found" )
3697 main.log.error( self.name + ": " + self.handle.before )
3698 main.cleanup()
3699 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003700 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003701 main.log.exception( self.name + ": Uncaught exception!" )
3702 main.cleanup()
3703 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003704
3705 def appIDs( self, jsonFormat=True ):
3706 """
3707 Show the mappings between app id and app names given by the 'app-ids'
3708 cli command
3709 """
3710 try:
3711 cmdStr = "app-ids"
3712 if jsonFormat:
3713 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003714 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003715 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003716 assert "Command not found:" not in output, output
3717 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003718 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003719 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003720 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003721 return None
3722 except TypeError:
3723 main.log.exception( self.name + ": Object not as expected" )
3724 return None
3725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
3728 main.cleanup()
3729 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003730 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003731 main.log.exception( self.name + ": Uncaught exception!" )
3732 main.cleanup()
3733 main.exit()
3734
3735 def appToIDCheck( self ):
3736 """
3737 This method will check that each application's ID listed in 'apps' is
3738 the same as the ID listed in 'app-ids'. The check will also check that
3739 there are no duplicate IDs issued. Note that an app ID should be
3740 a globaly unique numerical identifier for app/app-like features. Once
3741 an ID is registered, the ID is never freed up so that if an app is
3742 reinstalled it will have the same ID.
3743
3744 Returns: main.TRUE if the check passes and
3745 main.FALSE if the check fails or
3746 main.ERROR if there is some error in processing the test
3747 """
3748 try:
Jon Hall390696c2015-05-05 17:13:41 -07003749 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003750 rawJson = self.appIDs( jsonFormat=True )
3751 if rawJson:
3752 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003753 else:
Jon Hallc6793552016-01-19 14:18:37 -08003754 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003755 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003756 rawJson = self.apps( jsonFormat=True )
3757 if rawJson:
3758 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003759 else:
Jon Hallc6793552016-01-19 14:18:37 -08003760 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003761 bail = True
3762 if bail:
3763 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003764 result = main.TRUE
3765 for app in apps:
3766 appID = app.get( 'id' )
3767 if appID is None:
3768 main.log.error( "Error parsing app: " + str( app ) )
3769 result = main.FALSE
3770 appName = app.get( 'name' )
3771 if appName is None:
3772 main.log.error( "Error parsing app: " + str( app ) )
3773 result = main.FALSE
3774 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003775 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003776 # main.log.debug( "Comparing " + str( app ) + " to " +
3777 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003778 if not current: # if ids doesn't have this id
3779 result = main.FALSE
3780 main.log.error( "'app-ids' does not have the ID for " +
3781 str( appName ) + " that apps does." )
3782 elif len( current ) > 1:
3783 # there is more than one app with this ID
3784 result = main.FALSE
3785 # We will log this later in the method
3786 elif not current[0][ 'name' ] == appName:
3787 currentName = current[0][ 'name' ]
3788 result = main.FALSE
3789 main.log.error( "'app-ids' has " + str( currentName ) +
3790 " registered under id:" + str( appID ) +
3791 " but 'apps' has " + str( appName ) )
3792 else:
3793 pass # id and name match!
3794 # now make sure that app-ids has no duplicates
3795 idsList = []
3796 namesList = []
3797 for item in ids:
3798 idsList.append( item[ 'id' ] )
3799 namesList.append( item[ 'name' ] )
3800 if len( idsList ) != len( set( idsList ) ) or\
3801 len( namesList ) != len( set( namesList ) ):
3802 main.log.error( "'app-ids' has some duplicate entries: \n"
3803 + json.dumps( ids,
3804 sort_keys=True,
3805 indent=4,
3806 separators=( ',', ': ' ) ) )
3807 result = main.FALSE
3808 return result
Jon Hallc6793552016-01-19 14:18:37 -08003809 except ( TypeError, ValueError ):
3810 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003811 return main.ERROR
3812 except pexpect.EOF:
3813 main.log.error( self.name + ": EOF exception found" )
3814 main.log.error( self.name + ": " + self.handle.before )
3815 main.cleanup()
3816 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003817 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003818 main.log.exception( self.name + ": Uncaught exception!" )
3819 main.cleanup()
3820 main.exit()
3821
Jon Hallfb760a02015-04-13 15:35:03 -07003822 def getCfg( self, component=None, propName=None, short=False,
3823 jsonFormat=True ):
3824 """
3825 Get configuration settings from onos cli
3826 Optional arguments:
3827 component - Optionally only list configurations for a specific
3828 component. If None, all components with configurations
3829 are displayed. Case Sensitive string.
3830 propName - If component is specified, propName option will show
3831 only this specific configuration from that component.
3832 Case Sensitive string.
3833 jsonFormat - Returns output as json. Note that this will override
3834 the short option
3835 short - Short, less verbose, version of configurations.
3836 This is overridden by the json option
3837 returns:
3838 Output from cli as a string or None on error
3839 """
3840 try:
3841 baseStr = "cfg"
3842 cmdStr = " get"
3843 componentStr = ""
3844 if component:
3845 componentStr += " " + component
3846 if propName:
3847 componentStr += " " + propName
3848 if jsonFormat:
3849 baseStr += " -j"
3850 elif short:
3851 baseStr += " -s"
3852 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003853 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003854 assert "Command not found:" not in output, output
3855 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003856 return output
3857 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003858 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003859 return None
3860 except TypeError:
3861 main.log.exception( self.name + ": Object not as expected" )
3862 return None
3863 except pexpect.EOF:
3864 main.log.error( self.name + ": EOF exception found" )
3865 main.log.error( self.name + ": " + self.handle.before )
3866 main.cleanup()
3867 main.exit()
3868 except Exception:
3869 main.log.exception( self.name + ": Uncaught exception!" )
3870 main.cleanup()
3871 main.exit()
3872
3873 def setCfg( self, component, propName, value=None, check=True ):
3874 """
3875 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003876 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003877 component - The case sensitive name of the component whose
3878 property is to be set
3879 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003880 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003881 value - The value to set the property to. If None, will unset the
3882 property and revert it to it's default value(if applicable)
3883 check - Boolean, Check whether the option was successfully set this
3884 only applies when a value is given.
3885 returns:
3886 main.TRUE on success or main.FALSE on failure. If check is False,
3887 will return main.TRUE unless there is an error
3888 """
3889 try:
3890 baseStr = "cfg"
3891 cmdStr = " set " + str( component ) + " " + str( propName )
3892 if value is not None:
3893 cmdStr += " " + str( value )
3894 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003895 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003896 assert "Command not found:" not in output, output
3897 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003898 if value and check:
3899 results = self.getCfg( component=str( component ),
3900 propName=str( propName ),
3901 jsonFormat=True )
3902 # Check if current value is what we just set
3903 try:
3904 jsonOutput = json.loads( results )
3905 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003906 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003907 main.log.exception( "Error parsing cfg output" )
3908 main.log.error( "output:" + repr( results ) )
3909 return main.FALSE
3910 if current == str( value ):
3911 return main.TRUE
3912 return main.FALSE
3913 return main.TRUE
3914 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003915 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003916 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003917 except ( TypeError, ValueError ):
3918 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003919 return main.FALSE
3920 except pexpect.EOF:
3921 main.log.error( self.name + ": EOF exception found" )
3922 main.log.error( self.name + ": " + self.handle.before )
3923 main.cleanup()
3924 main.exit()
3925 except Exception:
3926 main.log.exception( self.name + ": Uncaught exception!" )
3927 main.cleanup()
3928 main.exit()
3929
Jon Hall390696c2015-05-05 17:13:41 -07003930 def setTestAdd( self, setName, values ):
3931 """
3932 CLI command to add elements to a distributed set.
3933 Arguments:
3934 setName - The name of the set to add to.
3935 values - The value(s) to add to the set, space seperated.
3936 Example usages:
3937 setTestAdd( "set1", "a b c" )
3938 setTestAdd( "set2", "1" )
3939 returns:
3940 main.TRUE on success OR
3941 main.FALSE if elements were already in the set OR
3942 main.ERROR on error
3943 """
3944 try:
3945 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3946 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003947 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003948 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003949 try:
3950 # TODO: Maybe make this less hardcoded
3951 # ConsistentMap Exceptions
3952 assert "org.onosproject.store.service" not in output
3953 # Node not leader
3954 assert "java.lang.IllegalStateException" not in output
3955 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003956 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003957 "command: " + str( output ) )
3958 retryTime = 30 # Conservative time, given by Madan
3959 main.log.info( "Waiting " + str( retryTime ) +
3960 "seconds before retrying." )
3961 time.sleep( retryTime ) # Due to change in mastership
3962 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003963 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003964 assert "Error executing command" not in output
3965 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3966 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3967 main.log.info( self.name + ": " + output )
3968 if re.search( positiveMatch, output):
3969 return main.TRUE
3970 elif re.search( negativeMatch, output):
3971 return main.FALSE
3972 else:
3973 main.log.error( self.name + ": setTestAdd did not" +
3974 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003975 main.log.debug( self.name + " actual: " + repr( output ) )
3976 return main.ERROR
3977 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003978 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003979 return main.ERROR
3980 except TypeError:
3981 main.log.exception( self.name + ": Object not as expected" )
3982 return main.ERROR
3983 except pexpect.EOF:
3984 main.log.error( self.name + ": EOF exception found" )
3985 main.log.error( self.name + ": " + self.handle.before )
3986 main.cleanup()
3987 main.exit()
3988 except Exception:
3989 main.log.exception( self.name + ": Uncaught exception!" )
3990 main.cleanup()
3991 main.exit()
3992
3993 def setTestRemove( self, setName, values, clear=False, retain=False ):
3994 """
3995 CLI command to remove elements from a distributed set.
3996 Required arguments:
3997 setName - The name of the set to remove from.
3998 values - The value(s) to remove from the set, space seperated.
3999 Optional arguments:
4000 clear - Clear all elements from the set
4001 retain - Retain only the given values. (intersection of the
4002 original set and the given set)
4003 returns:
4004 main.TRUE on success OR
4005 main.FALSE if the set was not changed OR
4006 main.ERROR on error
4007 """
4008 try:
4009 cmdStr = "set-test-remove "
4010 if clear:
4011 cmdStr += "-c " + str( setName )
4012 elif retain:
4013 cmdStr += "-r " + str( setName ) + " " + str( values )
4014 else:
4015 cmdStr += str( setName ) + " " + str( values )
4016 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004017 try:
Jon Halla495f562016-05-16 18:03:26 -07004018 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004019 # TODO: Maybe make this less hardcoded
4020 # ConsistentMap Exceptions
4021 assert "org.onosproject.store.service" not in output
4022 # Node not leader
4023 assert "java.lang.IllegalStateException" not in output
4024 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004025 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004026 "command: " + str( output ) )
4027 retryTime = 30 # Conservative time, given by Madan
4028 main.log.info( "Waiting " + str( retryTime ) +
4029 "seconds before retrying." )
4030 time.sleep( retryTime ) # Due to change in mastership
4031 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004032 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004033 assert "Command not found:" not in output, output
4034 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004035 main.log.info( self.name + ": " + output )
4036 if clear:
4037 pattern = "Set " + str( setName ) + " cleared"
4038 if re.search( pattern, output ):
4039 return main.TRUE
4040 elif retain:
4041 positivePattern = str( setName ) + " was pruned to contain " +\
4042 "only elements of set \[(.*)\]"
4043 negativePattern = str( setName ) + " was not changed by " +\
4044 "retaining only elements of the set " +\
4045 "\[(.*)\]"
4046 if re.search( positivePattern, output ):
4047 return main.TRUE
4048 elif re.search( negativePattern, output ):
4049 return main.FALSE
4050 else:
4051 positivePattern = "\[(.*)\] was removed from the set " +\
4052 str( setName )
4053 if ( len( values.split() ) == 1 ):
4054 negativePattern = "\[(.*)\] was not in set " +\
4055 str( setName )
4056 else:
4057 negativePattern = "No element of \[(.*)\] was in set " +\
4058 str( setName )
4059 if re.search( positivePattern, output ):
4060 return main.TRUE
4061 elif re.search( negativePattern, output ):
4062 return main.FALSE
4063 main.log.error( self.name + ": setTestRemove did not" +
4064 " match expected output" )
4065 main.log.debug( self.name + " expected: " + pattern )
4066 main.log.debug( self.name + " actual: " + repr( output ) )
4067 return main.ERROR
4068 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004069 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004070 return main.ERROR
4071 except TypeError:
4072 main.log.exception( self.name + ": Object not as expected" )
4073 return main.ERROR
4074 except pexpect.EOF:
4075 main.log.error( self.name + ": EOF exception found" )
4076 main.log.error( self.name + ": " + self.handle.before )
4077 main.cleanup()
4078 main.exit()
4079 except Exception:
4080 main.log.exception( self.name + ": Uncaught exception!" )
4081 main.cleanup()
4082 main.exit()
4083
4084 def setTestGet( self, setName, values="" ):
4085 """
4086 CLI command to get the elements in a distributed set.
4087 Required arguments:
4088 setName - The name of the set to remove from.
4089 Optional arguments:
4090 values - The value(s) to check if in the set, space seperated.
4091 returns:
4092 main.ERROR on error OR
4093 A list of elements in the set if no optional arguments are
4094 supplied OR
4095 A tuple containing the list then:
4096 main.FALSE if the given values are not in the set OR
4097 main.TRUE if the given values are in the set OR
4098 """
4099 try:
4100 values = str( values ).strip()
4101 setName = str( setName ).strip()
4102 length = len( values.split() )
4103 containsCheck = None
4104 # Patterns to match
4105 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004106 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004107 containsTrue = "Set " + setName + " contains the value " + values
4108 containsFalse = "Set " + setName + " did not contain the value " +\
4109 values
4110 containsAllTrue = "Set " + setName + " contains the the subset " +\
4111 setPattern
4112 containsAllFalse = "Set " + setName + " did not contain the the" +\
4113 " subset " + setPattern
4114
4115 cmdStr = "set-test-get "
4116 cmdStr += setName + " " + values
4117 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004118 try:
Jon Halla495f562016-05-16 18:03:26 -07004119 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004120 # TODO: Maybe make this less hardcoded
4121 # ConsistentMap Exceptions
4122 assert "org.onosproject.store.service" not in output
4123 # Node not leader
4124 assert "java.lang.IllegalStateException" not in output
4125 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004126 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004127 "command: " + str( output ) )
4128 retryTime = 30 # Conservative time, given by Madan
4129 main.log.info( "Waiting " + str( retryTime ) +
4130 "seconds before retrying." )
4131 time.sleep( retryTime ) # Due to change in mastership
4132 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004133 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004134 assert "Command not found:" not in output, output
4135 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004136 main.log.info( self.name + ": " + output )
4137
4138 if length == 0:
4139 match = re.search( pattern, output )
4140 else: # if given values
4141 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004142 patternTrue = pattern + "\r\n" + containsTrue
4143 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004144 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004145 patternTrue = pattern + "\r\n" + containsAllTrue
4146 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004147 matchTrue = re.search( patternTrue, output )
4148 matchFalse = re.search( patternFalse, output )
4149 if matchTrue:
4150 containsCheck = main.TRUE
4151 match = matchTrue
4152 elif matchFalse:
4153 containsCheck = main.FALSE
4154 match = matchFalse
4155 else:
4156 main.log.error( self.name + " setTestGet did not match " +\
4157 "expected output" )
4158 main.log.debug( self.name + " expected: " + pattern )
4159 main.log.debug( self.name + " actual: " + repr( output ) )
4160 match = None
4161 if match:
4162 setMatch = match.group( 1 )
4163 if setMatch == '':
4164 setList = []
4165 else:
4166 setList = setMatch.split( ", " )
4167 if length > 0:
4168 return ( setList, containsCheck )
4169 else:
4170 return setList
4171 else: # no match
4172 main.log.error( self.name + ": setTestGet did not" +
4173 " match expected output" )
4174 main.log.debug( self.name + " expected: " + pattern )
4175 main.log.debug( self.name + " actual: " + repr( output ) )
4176 return main.ERROR
4177 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004178 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004179 return main.ERROR
4180 except TypeError:
4181 main.log.exception( self.name + ": Object not as expected" )
4182 return main.ERROR
4183 except pexpect.EOF:
4184 main.log.error( self.name + ": EOF exception found" )
4185 main.log.error( self.name + ": " + self.handle.before )
4186 main.cleanup()
4187 main.exit()
4188 except Exception:
4189 main.log.exception( self.name + ": Uncaught exception!" )
4190 main.cleanup()
4191 main.exit()
4192
4193 def setTestSize( self, setName ):
4194 """
4195 CLI command to get the elements in a distributed set.
4196 Required arguments:
4197 setName - The name of the set to remove from.
4198 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004199 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004200 None on error
4201 """
4202 try:
4203 # TODO: Should this check against the number of elements returned
4204 # and then return true/false based on that?
4205 setName = str( setName ).strip()
4206 # Patterns to match
4207 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004208 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004209 setPattern
4210 cmdStr = "set-test-get -s "
4211 cmdStr += setName
4212 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004213 try:
Jon Halla495f562016-05-16 18:03:26 -07004214 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004215 # TODO: Maybe make this less hardcoded
4216 # ConsistentMap Exceptions
4217 assert "org.onosproject.store.service" not in output
4218 # Node not leader
4219 assert "java.lang.IllegalStateException" not in output
4220 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004221 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004222 "command: " + str( output ) )
4223 retryTime = 30 # Conservative time, given by Madan
4224 main.log.info( "Waiting " + str( retryTime ) +
4225 "seconds before retrying." )
4226 time.sleep( retryTime ) # Due to change in mastership
4227 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004228 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004229 assert "Command not found:" not in output, output
4230 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004231 main.log.info( self.name + ": " + output )
4232 match = re.search( pattern, output )
4233 if match:
4234 setSize = int( match.group( 1 ) )
4235 setMatch = match.group( 2 )
4236 if len( setMatch.split() ) == setSize:
4237 main.log.info( "The size returned by " + self.name +
4238 " matches the number of elements in " +
4239 "the returned set" )
4240 else:
4241 main.log.error( "The size returned by " + self.name +
4242 " does not match the number of " +
4243 "elements in the returned set." )
4244 return setSize
4245 else: # no match
4246 main.log.error( self.name + ": setTestGet did not" +
4247 " match expected output" )
4248 main.log.debug( self.name + " expected: " + pattern )
4249 main.log.debug( self.name + " actual: " + repr( output ) )
4250 return None
4251 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004252 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004253 return None
Jon Hall390696c2015-05-05 17:13:41 -07004254 except TypeError:
4255 main.log.exception( self.name + ": Object not as expected" )
4256 return None
4257 except pexpect.EOF:
4258 main.log.error( self.name + ": EOF exception found" )
4259 main.log.error( self.name + ": " + self.handle.before )
4260 main.cleanup()
4261 main.exit()
4262 except Exception:
4263 main.log.exception( self.name + ": Uncaught exception!" )
4264 main.cleanup()
4265 main.exit()
4266
Jon Hall80daded2015-05-27 16:07:00 -07004267 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004268 """
4269 Command to list the various counters in the system.
4270 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004271 if jsonFormat, a string of the json object returned by the cli
4272 command
4273 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004274 None on error
4275 """
Jon Hall390696c2015-05-05 17:13:41 -07004276 try:
4277 counters = {}
4278 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004279 if jsonFormat:
4280 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004281 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004282 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004283 assert "Command not found:" not in output, output
4284 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004285 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004286 return output
Jon Hall390696c2015-05-05 17:13:41 -07004287 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004288 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004289 return None
Jon Hall390696c2015-05-05 17:13:41 -07004290 except TypeError:
4291 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004292 return None
Jon Hall390696c2015-05-05 17:13:41 -07004293 except pexpect.EOF:
4294 main.log.error( self.name + ": EOF exception found" )
4295 main.log.error( self.name + ": " + self.handle.before )
4296 main.cleanup()
4297 main.exit()
4298 except Exception:
4299 main.log.exception( self.name + ": Uncaught exception!" )
4300 main.cleanup()
4301 main.exit()
4302
Jon Hall935db192016-04-19 00:22:04 -07004303 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004304 """
Jon Halle1a3b752015-07-22 13:02:46 -07004305 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004306 Required arguments:
4307 counter - The name of the counter to increment.
4308 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004309 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004310 returns:
4311 integer value of the counter or
4312 None on Error
4313 """
4314 try:
4315 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004316 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004317 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004318 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004319 if delta != 1:
4320 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004321 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004322 try:
Jon Halla495f562016-05-16 18:03:26 -07004323 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004324 # TODO: Maybe make this less hardcoded
4325 # ConsistentMap Exceptions
4326 assert "org.onosproject.store.service" not in output
4327 # Node not leader
4328 assert "java.lang.IllegalStateException" not in output
4329 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004330 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004331 "command: " + str( output ) )
4332 retryTime = 30 # Conservative time, given by Madan
4333 main.log.info( "Waiting " + str( retryTime ) +
4334 "seconds before retrying." )
4335 time.sleep( retryTime ) # Due to change in mastership
4336 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004337 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004338 assert "Command not found:" not in output, output
4339 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004340 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004341 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004342 match = re.search( pattern, output )
4343 if match:
4344 return int( match.group( 1 ) )
4345 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004346 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004347 " match expected output." )
4348 main.log.debug( self.name + " expected: " + pattern )
4349 main.log.debug( self.name + " actual: " + repr( output ) )
4350 return None
4351 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004352 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004353 return None
4354 except TypeError:
4355 main.log.exception( self.name + ": Object not as expected" )
4356 return None
4357 except pexpect.EOF:
4358 main.log.error( self.name + ": EOF exception found" )
4359 main.log.error( self.name + ": " + self.handle.before )
4360 main.cleanup()
4361 main.exit()
4362 except Exception:
4363 main.log.exception( self.name + ": Uncaught exception!" )
4364 main.cleanup()
4365 main.exit()
4366
Jon Hall935db192016-04-19 00:22:04 -07004367 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004368 """
4369 CLI command to get a distributed counter then add a delta to it.
4370 Required arguments:
4371 counter - The name of the counter to increment.
4372 Optional arguments:
4373 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004374 returns:
4375 integer value of the counter or
4376 None on Error
4377 """
4378 try:
4379 counter = str( counter )
4380 delta = int( delta )
4381 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004382 cmdStr += counter
4383 if delta != 1:
4384 cmdStr += " " + str( delta )
4385 output = self.sendline( cmdStr )
4386 try:
Jon Halla495f562016-05-16 18:03:26 -07004387 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004388 # TODO: Maybe make this less hardcoded
4389 # ConsistentMap Exceptions
4390 assert "org.onosproject.store.service" not in output
4391 # Node not leader
4392 assert "java.lang.IllegalStateException" not in output
4393 except AssertionError:
4394 main.log.error( "Error in processing '" + cmdStr + "' " +
4395 "command: " + str( output ) )
4396 retryTime = 30 # Conservative time, given by Madan
4397 main.log.info( "Waiting " + str( retryTime ) +
4398 "seconds before retrying." )
4399 time.sleep( retryTime ) # Due to change in mastership
4400 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004401 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004402 assert "Command not found:" not in output, output
4403 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004404 main.log.info( self.name + ": " + output )
4405 pattern = counter + " was updated to (-?\d+)"
4406 match = re.search( pattern, output )
4407 if match:
4408 return int( match.group( 1 ) )
4409 else:
4410 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4411 " match expected output." )
4412 main.log.debug( self.name + " expected: " + pattern )
4413 main.log.debug( self.name + " actual: " + repr( output ) )
4414 return None
4415 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004416 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004417 return None
4418 except TypeError:
4419 main.log.exception( self.name + ": Object not as expected" )
4420 return None
4421 except pexpect.EOF:
4422 main.log.error( self.name + ": EOF exception found" )
4423 main.log.error( self.name + ": " + self.handle.before )
4424 main.cleanup()
4425 main.exit()
4426 except Exception:
4427 main.log.exception( self.name + ": Uncaught exception!" )
4428 main.cleanup()
4429 main.exit()
4430
YPZhangfebf7302016-05-24 16:45:56 -07004431 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004432 """
4433 Description: Execute summary command in onos
4434 Returns: json object ( summary -j ), returns main.FALSE if there is
4435 no output
4436
4437 """
4438 try:
4439 cmdStr = "summary"
4440 if jsonFormat:
4441 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004442 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004443 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004444 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004445 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004446 if not handle:
4447 main.log.error( self.name + ": There is no output in " +
4448 "summary command" )
4449 return main.FALSE
4450 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004451 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004452 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004453 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004454 except TypeError:
4455 main.log.exception( self.name + ": Object not as expected" )
4456 return None
4457 except pexpect.EOF:
4458 main.log.error( self.name + ": EOF exception found" )
4459 main.log.error( self.name + ": " + self.handle.before )
4460 main.cleanup()
4461 main.exit()
4462 except Exception:
4463 main.log.exception( self.name + ": Uncaught exception!" )
4464 main.cleanup()
4465 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004466
Jon Hall935db192016-04-19 00:22:04 -07004467 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004468 """
4469 CLI command to get the value of a key in a consistent map using
4470 transactions. This a test function and can only get keys from the
4471 test map hard coded into the cli command
4472 Required arguments:
4473 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004474 returns:
4475 The string value of the key or
4476 None on Error
4477 """
4478 try:
4479 keyName = str( keyName )
4480 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004481 cmdStr += keyName
4482 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004483 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004484 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004485 try:
4486 # TODO: Maybe make this less hardcoded
4487 # ConsistentMap Exceptions
4488 assert "org.onosproject.store.service" not in output
4489 # Node not leader
4490 assert "java.lang.IllegalStateException" not in output
4491 except AssertionError:
4492 main.log.error( "Error in processing '" + cmdStr + "' " +
4493 "command: " + str( output ) )
4494 return None
4495 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4496 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004497 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004498 return None
4499 else:
4500 match = re.search( pattern, output )
4501 if match:
4502 return match.groupdict()[ 'value' ]
4503 else:
4504 main.log.error( self.name + ": transactionlMapGet did not" +
4505 " match expected output." )
4506 main.log.debug( self.name + " expected: " + pattern )
4507 main.log.debug( self.name + " actual: " + repr( output ) )
4508 return None
Jon Hallc6793552016-01-19 14:18:37 -08004509 except AssertionError:
4510 main.log.exception( "" )
4511 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004512 except TypeError:
4513 main.log.exception( self.name + ": Object not as expected" )
4514 return None
4515 except pexpect.EOF:
4516 main.log.error( self.name + ": EOF exception found" )
4517 main.log.error( self.name + ": " + self.handle.before )
4518 main.cleanup()
4519 main.exit()
4520 except Exception:
4521 main.log.exception( self.name + ": Uncaught exception!" )
4522 main.cleanup()
4523 main.exit()
4524
Jon Hall935db192016-04-19 00:22:04 -07004525 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004526 """
4527 CLI command to put a value into 'numKeys' number of keys in a
4528 consistent map using transactions. This a test function and can only
4529 put into keys named 'Key#' of the test map hard coded into the cli command
4530 Required arguments:
4531 numKeys - Number of keys to add the value to
4532 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004533 returns:
4534 A dictionary whose keys are the name of the keys put into the map
4535 and the values of the keys are dictionaries whose key-values are
4536 'value': value put into map and optionaly
4537 'oldValue': Previous value in the key or
4538 None on Error
4539
4540 Example output
4541 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4542 'Key2': {'value': 'Testing'} }
4543 """
4544 try:
4545 numKeys = str( numKeys )
4546 value = str( value )
4547 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004548 cmdStr += numKeys + " " + value
4549 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004550 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004551 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004552 try:
4553 # TODO: Maybe make this less hardcoded
4554 # ConsistentMap Exceptions
4555 assert "org.onosproject.store.service" not in output
4556 # Node not leader
4557 assert "java.lang.IllegalStateException" not in output
4558 except AssertionError:
4559 main.log.error( "Error in processing '" + cmdStr + "' " +
4560 "command: " + str( output ) )
4561 return None
4562 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4563 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4564 results = {}
4565 for line in output.splitlines():
4566 new = re.search( newPattern, line )
4567 updated = re.search( updatedPattern, line )
4568 if new:
4569 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4570 elif updated:
4571 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004572 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004573 else:
4574 main.log.error( self.name + ": transactionlMapGet did not" +
4575 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004576 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4577 newPattern,
4578 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004579 main.log.debug( self.name + " actual: " + repr( output ) )
4580 return results
Jon Hallc6793552016-01-19 14:18:37 -08004581 except AssertionError:
4582 main.log.exception( "" )
4583 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004584 except TypeError:
4585 main.log.exception( self.name + ": Object not as expected" )
4586 return None
4587 except pexpect.EOF:
4588 main.log.error( self.name + ": EOF exception found" )
4589 main.log.error( self.name + ": " + self.handle.before )
4590 main.cleanup()
4591 main.exit()
4592 except Exception:
4593 main.log.exception( self.name + ": Uncaught exception!" )
4594 main.cleanup()
4595 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004596
acsmarsdaea66c2015-09-03 11:44:06 -07004597 def maps( self, jsonFormat=True ):
4598 """
4599 Description: Returns result of onos:maps
4600 Optional:
4601 * jsonFormat: enable json formatting of output
4602 """
4603 try:
4604 cmdStr = "maps"
4605 if jsonFormat:
4606 cmdStr += " -j"
4607 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004608 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004609 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004610 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004611 except AssertionError:
4612 main.log.exception( "" )
4613 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004614 except TypeError:
4615 main.log.exception( self.name + ": Object not as expected" )
4616 return None
4617 except pexpect.EOF:
4618 main.log.error( self.name + ": EOF exception found" )
4619 main.log.error( self.name + ": " + self.handle.before )
4620 main.cleanup()
4621 main.exit()
4622 except Exception:
4623 main.log.exception( self.name + ": Uncaught exception!" )
4624 main.cleanup()
4625 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004626
4627 def getSwController( self, uri, jsonFormat=True ):
4628 """
4629 Descrition: Gets the controller information from the device
4630 """
4631 try:
4632 cmd = "device-controllers "
4633 if jsonFormat:
4634 cmd += "-j "
4635 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004636 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004637 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004638 return response
Jon Hallc6793552016-01-19 14:18:37 -08004639 except AssertionError:
4640 main.log.exception( "" )
4641 return None
GlennRC050596c2015-11-18 17:06:41 -08004642 except TypeError:
4643 main.log.exception( self.name + ": Object not as expected" )
4644 return None
4645 except pexpect.EOF:
4646 main.log.error( self.name + ": EOF exception found" )
4647 main.log.error( self.name + ": " + self.handle.before )
4648 main.cleanup()
4649 main.exit()
4650 except Exception:
4651 main.log.exception( self.name + ": Uncaught exception!" )
4652 main.cleanup()
4653 main.exit()
4654
4655 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4656 """
4657 Descrition: sets the controller(s) for the specified device
4658
4659 Parameters:
4660 Required: uri - String: The uri of the device(switch).
4661 ip - String or List: The ip address of the controller.
4662 This parameter can be formed in a couple of different ways.
4663 VALID:
4664 10.0.0.1 - just the ip address
4665 tcp:10.0.0.1 - the protocol and the ip address
4666 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4667 so that you can add controllers with different
4668 protocols and ports
4669 INVALID:
4670 10.0.0.1:6653 - this is not supported by ONOS
4671
4672 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4673 port - The port number.
4674 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4675
4676 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4677 """
4678 try:
4679 cmd = "device-setcontrollers"
4680
4681 if jsonFormat:
4682 cmd += " -j"
4683 cmd += " " + uri
4684 if isinstance( ip, str ):
4685 ip = [ip]
4686 for item in ip:
4687 if ":" in item:
4688 sitem = item.split( ":" )
4689 if len(sitem) == 3:
4690 cmd += " " + item
4691 elif "." in sitem[1]:
4692 cmd += " {}:{}".format(item, port)
4693 else:
4694 main.log.error( "Malformed entry: " + item )
4695 raise TypeError
4696 else:
4697 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004698 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004699 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004700 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004701 if "Error" in response:
4702 main.log.error( response )
4703 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004704 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004705 except AssertionError:
4706 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004707 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004708 except TypeError:
4709 main.log.exception( self.name + ": Object not as expected" )
4710 return main.FALSE
4711 except pexpect.EOF:
4712 main.log.error( self.name + ": EOF exception found" )
4713 main.log.error( self.name + ": " + self.handle.before )
4714 main.cleanup()
4715 main.exit()
4716 except Exception:
4717 main.log.exception( self.name + ": Uncaught exception!" )
4718 main.cleanup()
4719 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004720
4721 def removeDevice( self, device ):
4722 '''
4723 Description:
4724 Remove a device from ONOS by passing the uri of the device(s).
4725 Parameters:
4726 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4727 Returns:
4728 Returns main.FALSE if an exception is thrown or an error is present
4729 in the response. Otherwise, returns main.TRUE.
4730 NOTE:
4731 If a host cannot be removed, then this function will return main.FALSE
4732 '''
4733 try:
4734 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004735 deviceStr = device
4736 device = []
4737 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004738
4739 for d in device:
4740 time.sleep( 1 )
4741 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004742 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004743 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004744 if "Error" in response:
4745 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4746 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004747 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004748 except AssertionError:
4749 main.log.exception( "" )
4750 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004751 except TypeError:
4752 main.log.exception( self.name + ": Object not as expected" )
4753 return main.FALSE
4754 except pexpect.EOF:
4755 main.log.error( self.name + ": EOF exception found" )
4756 main.log.error( self.name + ": " + self.handle.before )
4757 main.cleanup()
4758 main.exit()
4759 except Exception:
4760 main.log.exception( self.name + ": Uncaught exception!" )
4761 main.cleanup()
4762 main.exit()
4763
4764 def removeHost( self, host ):
4765 '''
4766 Description:
4767 Remove a host from ONOS by passing the id of the host(s)
4768 Parameters:
4769 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4770 Returns:
4771 Returns main.FALSE if an exception is thrown or an error is present
4772 in the response. Otherwise, returns main.TRUE.
4773 NOTE:
4774 If a host cannot be removed, then this function will return main.FALSE
4775 '''
4776 try:
4777 if type( host ) is str:
4778 host = list( host )
4779
4780 for h in host:
4781 time.sleep( 1 )
4782 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004783 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004784 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004785 if "Error" in response:
4786 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4787 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004788 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004789 except AssertionError:
4790 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004791 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004792 except TypeError:
4793 main.log.exception( self.name + ": Object not as expected" )
4794 return main.FALSE
4795 except pexpect.EOF:
4796 main.log.error( self.name + ": EOF exception found" )
4797 main.log.error( self.name + ": " + self.handle.before )
4798 main.cleanup()
4799 main.exit()
4800 except Exception:
4801 main.log.exception( self.name + ": Uncaught exception!" )
4802 main.cleanup()
4803 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004804
YPZhangfebf7302016-05-24 16:45:56 -07004805 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004806 '''
4807 Description:
4808 Bring link down or up in the null-provider.
4809 params:
4810 begin - (string) One end of a device or switch.
4811 end - (string) the other end of the device or switch
4812 returns:
4813 main.TRUE if no exceptions were thrown and no Errors are
4814 present in the resoponse. Otherwise, returns main.FALSE
4815 '''
4816 try:
Jon Hallc6793552016-01-19 14:18:37 -08004817 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004818 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004819 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004820 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004821 if "Error" in response or "Failure" in response:
4822 main.log.error( response )
4823 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004824 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004825 except AssertionError:
4826 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004827 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004828 except TypeError:
4829 main.log.exception( self.name + ": Object not as expected" )
4830 return main.FALSE
4831 except pexpect.EOF:
4832 main.log.error( self.name + ": EOF exception found" )
4833 main.log.error( self.name + ": " + self.handle.before )
4834 main.cleanup()
4835 main.exit()
4836 except Exception:
4837 main.log.exception( self.name + ": Uncaught exception!" )
4838 main.cleanup()
4839 main.exit()
4840
Jon Hall2c8959e2016-12-16 12:17:34 -08004841 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004842 '''
4843 Description:
4844 Changes the state of port in an OF switch by means of the
4845 PORTSTATUS OF messages.
4846 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004847 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4848 port - (string) target port in the device. Ex: '2'
4849 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004850 returns:
4851 main.TRUE if no exceptions were thrown and no Errors are
4852 present in the resoponse. Otherwise, returns main.FALSE
4853 '''
4854 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004855 state = state.lower()
4856 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004857 cmd = "portstate {} {} {}".format( dpid, port, state )
4858 response = self.sendline( cmd, showResponse=True )
4859 assert response is not None, "Error in sendline"
4860 assert "Command not found:" not in response, response
4861 if "Error" in response or "Failure" in response:
4862 main.log.error( response )
4863 return main.FALSE
4864 return main.TRUE
4865 except AssertionError:
4866 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004867 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004868 except TypeError:
4869 main.log.exception( self.name + ": Object not as expected" )
4870 return main.FALSE
4871 except pexpect.EOF:
4872 main.log.error( self.name + ": EOF exception found" )
4873 main.log.error( self.name + ": " + self.handle.before )
4874 main.cleanup()
4875 main.exit()
4876 except Exception:
4877 main.log.exception( self.name + ": Uncaught exception!" )
4878 main.cleanup()
4879 main.exit()
4880
4881 def logSet( self, level="INFO", app="org.onosproject" ):
4882 """
4883 Set the logging level to lvl for a specific app
4884 returns main.TRUE on success
4885 returns main.FALSE if Error occurred
4886 if noExit is True, TestON will not exit, but clean up
4887 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4888 Level defaults to INFO
4889 """
4890 try:
4891 self.handle.sendline( "log:set %s %s" %( level, app ) )
4892 self.handle.expect( "onos>" )
4893
4894 response = self.handle.before
4895 if re.search( "Error", response ):
4896 return main.FALSE
4897 return main.TRUE
4898 except pexpect.TIMEOUT:
4899 main.log.exception( self.name + ": TIMEOUT exception found" )
4900 main.cleanup()
4901 main.exit()
4902 except pexpect.EOF:
4903 main.log.error( self.name + ": EOF exception found" )
4904 main.log.error( self.name + ": " + self.handle.before )
4905 main.cleanup()
4906 main.exit()
4907 except Exception:
4908 main.log.exception( self.name + ": Uncaught exception!" )
4909 main.cleanup()
4910 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004911
4912 def getGraphDict( self, timeout=60, includeHost=False ):
4913 """
4914 Return a dictionary which describes the latest network topology data as a
4915 graph.
4916 An example of the dictionary:
4917 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4918 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4919 Each vertex should at least have an 'edges' attribute which describes the
4920 adjacency information. The value of 'edges' attribute is also represented by
4921 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4922 list of attributes.
4923 An example of the edges dictionary:
4924 'edges': { vertex2: { 'port': ..., 'weight': ... },
4925 vertex3: { 'port': ..., 'weight': ... } }
4926 If includeHost == True, all hosts (and host-switch links) will be included
4927 in topology data.
4928 """
4929 graphDict = {}
4930 try:
4931 links = self.links()
4932 links = json.loads( links )
4933 devices = self.devices()
4934 devices = json.loads( devices )
4935 idToDevice = {}
4936 for device in devices:
4937 idToDevice[ device[ 'id' ] ] = device
4938 if includeHost:
4939 hosts = self.hosts()
4940 # FIXME: support 'includeHost' argument
4941 for link in links:
4942 nodeA = link[ 'src' ][ 'device' ]
4943 nodeB = link[ 'dst' ][ 'device' ]
4944 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4945 if not nodeA in graphDict.keys():
4946 graphDict[ nodeA ] = { 'edges':{},
4947 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4948 'type':idToDevice[ nodeA ][ 'type' ],
4949 'available':idToDevice[ nodeA ][ 'available' ],
4950 'role':idToDevice[ nodeA ][ 'role' ],
4951 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4952 'hw':idToDevice[ nodeA ][ 'hw' ],
4953 'sw':idToDevice[ nodeA ][ 'sw' ],
4954 'serial':idToDevice[ nodeA ][ 'serial' ],
4955 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4956 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4957 else:
4958 # Assert nodeB is not connected to any current links of nodeA
4959 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4960 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4961 'type':link[ 'type' ],
4962 'state':link[ 'state' ] }
4963 return graphDict
4964 except ( TypeError, ValueError ):
4965 main.log.exception( self.name + ": Object not as expected" )
4966 return None
4967 except KeyError:
4968 main.log.exception( self.name + ": KeyError exception found" )
4969 return None
4970 except AssertionError:
4971 main.log.exception( self.name + ": AssertionError exception found" )
4972 return None
4973 except pexpect.EOF:
4974 main.log.error( self.name + ": EOF exception found" )
4975 main.log.error( self.name + ": " + self.handle.before )
4976 return None
4977 except Exception:
4978 main.log.exception( self.name + ": Uncaught exception!" )
4979 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004980
4981 def getIntentPerfSummary( self ):
4982 '''
4983 Send command to check intent-perf summary
4984 Returns: dictionary for intent-perf summary
4985 if something wrong, function will return None
4986 '''
4987 cmd = "intent-perf -s"
4988 respDic = {}
4989 resp = self.sendline( cmd )
4990 try:
4991 # Generate the dictionary to return
4992 for l in resp.split( "\n" ):
4993 # Delete any white space in line
4994 temp = re.sub( r'\s+', '', l )
4995 temp = temp.split( ":" )
4996 respDic[ temp[0] ] = temp[ 1 ]
4997
4998 except (TypeError, ValueError):
4999 main.log.exception( self.name + ": Object not as expected" )
5000 return None
5001 except KeyError:
5002 main.log.exception( self.name + ": KeyError exception found" )
5003 return None
5004 except AssertionError:
5005 main.log.exception( self.name + ": AssertionError exception found" )
5006 return None
5007 except pexpect.EOF:
5008 main.log.error( self.name + ": EOF exception found" )
5009 main.log.error( self.name + ": " + self.handle.before )
5010 return None
5011 except Exception:
5012 main.log.exception( self.name + ": Uncaught exception!" )
5013 return None
5014 return respDic
5015
Chiyu Chengec63bde2016-11-17 18:11:36 -08005016 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005017 """
5018 Searches the latest ONOS log file for the given search term and
5019 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005020
chengchiyu08303a02016-09-08 17:40:26 -07005021 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005022 searchTerm:
5023 The string to grep from the ONOS log.
5024 startLine:
5025 The term that decides which line is the start to search the searchTerm in
5026 the karaf log. For now, startTerm only works in 'first' mode.
5027 logNum:
5028 In some extreme cases, one karaf log is not big enough to contain all the
5029 information.Because of this, search mutiply logs is necessary to capture
5030 the right result. logNum is the number of karaf logs that we need to search
5031 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005032 mode:
5033 all: return all the strings that contain the search term
5034 last: return the last string that contains the search term
5035 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005036 num: return the number of times that the searchTerm appears in the log
5037 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005038 """
5039 try:
5040 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005041 #Build the log paths string
5042 logPath = '/opt/onos/log/karaf.log.'
5043 logPaths = '/opt/onos/log/karaf.log'
5044 for i in range( 1, logNum ):
5045 logPaths = logPath + str( i ) + " " + logPaths
5046 cmd = "cat " + logPaths
5047 if mode == 'all':
5048 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005049 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005050 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005051 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005052 if startLine != '':
5053 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5054 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5055 else:
5056 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005057 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005058 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005059 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005060 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005061 if mode == 'total':
5062 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5063 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005064 before = self.sendline( cmd )
5065 before = before.splitlines()
5066 # make sure the returned list only contains the search term
5067 returnLines = [line for line in before if searchTerm in line]
5068 return returnLines
5069 except AssertionError:
5070 main.log.error( self.name + " searchTerm is not string type" )
5071 return None
5072 except pexpect.EOF:
5073 main.log.error( self.name + ": EOF exception found" )
5074 main.log.error( self.name + ": " + self.handle.before )
5075 main.cleanup()
5076 main.exit()
5077 except pexpect.TIMEOUT:
5078 main.log.error( self.name + ": TIMEOUT exception found" )
5079 main.log.error( self.name + ": " + self.handle.before )
5080 main.cleanup()
5081 main.exit()
5082 except Exception:
5083 main.log.exception( self.name + ": Uncaught exception!" )
5084 main.cleanup()
5085 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005086
5087 def vplsShow( self, jsonFormat=True ):
5088 """
5089 Description: Returns result of onos:vpls show, which should list the
5090 configured VPLS networks and the assigned interfaces.
5091 Optional:
5092 * jsonFormat: enable json formatting of output
5093 Returns:
5094 The output of the command or None on error.
5095 """
5096 try:
5097 cmdStr = "vpls show"
5098 if jsonFormat:
5099 raise NotImplementedError
5100 cmdStr += " -j"
5101 handle = self.sendline( cmdStr )
5102 assert handle is not None, "Error in sendline"
5103 assert "Command not found:" not in handle, handle
5104 return handle
5105 except AssertionError:
5106 main.log.exception( "" )
5107 return None
5108 except TypeError:
5109 main.log.exception( self.name + ": Object not as expected" )
5110 return None
5111 except pexpect.EOF:
5112 main.log.error( self.name + ": EOF exception found" )
5113 main.log.error( self.name + ": " + self.handle.before )
5114 main.cleanup()
5115 main.exit()
5116 except NotImplementedError:
5117 main.log.exception( self.name + ": Json output not supported")
5118 return None
5119 except Exception:
5120 main.log.exception( self.name + ": Uncaught exception!" )
5121 main.cleanup()
5122 main.exit()
5123
5124 def parseVplsShow( self ):
5125 """
5126 Parse the cli output of 'vpls show' into json output. This is required
5127 as there is currently no json output available.
5128 """
5129 try:
5130 output = []
5131 raw = self.vplsShow( jsonFormat=False )
5132 namePat = "VPLS name: (?P<name>\w+)"
5133 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5134 encapPat = "Encapsulation: (?P<encap>\w+)"
5135 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5136 mIter = re.finditer( pattern, raw )
5137 for match in mIter:
5138 item = {}
5139 item[ 'name' ] = match.group( 'name' )
5140 ifaces = match.group( 'interfaces' ).split( ', ')
5141 if ifaces == [ "" ]:
5142 ifaces = []
5143 item[ 'interfaces' ] = ifaces
5144 encap = match.group( 'encap' )
5145 if encap != 'NONE':
5146 item[ 'encapsulation' ] = encap.lower()
5147 output.append( item )
5148 return output
5149 except Exception:
5150 main.log.exception( self.name + ": Uncaught exception!" )
5151 main.cleanup()
5152 main.exit()
5153
5154 def vplsList( self, jsonFormat=True ):
5155 """
5156 Description: Returns result of onos:vpls list, which should list the
5157 configured VPLS networks.
5158 Optional:
5159 * jsonFormat: enable json formatting of output
5160 """
5161 try:
5162 cmdStr = "vpls list"
5163 if jsonFormat:
5164 raise NotImplementedError
5165 cmdStr += " -j"
5166 handle = self.sendline( cmdStr )
5167 assert handle is not None, "Error in sendline"
5168 assert "Command not found:" not in handle, handle
5169 return handle
5170 except AssertionError:
5171 main.log.exception( "" )
5172 return None
5173 except TypeError:
5174 main.log.exception( self.name + ": Object not as expected" )
5175 return None
5176 except pexpect.EOF:
5177 main.log.error( self.name + ": EOF exception found" )
5178 main.log.error( self.name + ": " + self.handle.before )
5179 main.cleanup()
5180 main.exit()
5181 except NotImplementedError:
5182 main.log.exception( self.name + ": Json output not supported")
5183 return None
5184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
5186 main.cleanup()
5187 main.exit()
5188
5189 def vplsCreate( self, network ):
5190 """
5191 CLI command to create a new VPLS network.
5192 Required arguments:
5193 network - String name of the network to create.
5194 returns:
5195 main.TRUE on success and main.FALSE on failure
5196 """
5197 try:
5198 network = str( network )
5199 cmdStr = "vpls create "
5200 cmdStr += network
5201 output = self.sendline( cmdStr )
5202 assert output is not None, "Error in sendline"
5203 assert "Command not found:" not in output, output
5204 assert "Error executing command" not in output, output
5205 assert "VPLS already exists:" not in output, output
5206 return main.TRUE
5207 except AssertionError:
5208 main.log.exception( "" )
5209 return main.FALSE
5210 except TypeError:
5211 main.log.exception( self.name + ": Object not as expected" )
5212 return main.FALSE
5213 except pexpect.EOF:
5214 main.log.error( self.name + ": EOF exception found" )
5215 main.log.error( self.name + ": " + self.handle.before )
5216 main.cleanup()
5217 main.exit()
5218 except Exception:
5219 main.log.exception( self.name + ": Uncaught exception!" )
5220 main.cleanup()
5221 main.exit()
5222
5223 def vplsDelete( self, network ):
5224 """
5225 CLI command to delete a VPLS network.
5226 Required arguments:
5227 network - Name of the network to delete.
5228 returns:
5229 main.TRUE on success and main.FALSE on failure
5230 """
5231 try:
5232 network = str( network )
5233 cmdStr = "vpls delete "
5234 cmdStr += network
5235 output = self.sendline( cmdStr )
5236 assert output is not None, "Error in sendline"
5237 assert "Command not found:" not in output, output
5238 assert "Error executing command" not in output, output
5239 assert " not found" not in output, output
5240 return main.TRUE
5241 except AssertionError:
5242 main.log.exception( "" )
5243 return main.FALSE
5244 except TypeError:
5245 main.log.exception( self.name + ": Object not as expected" )
5246 return main.FALSE
5247 except pexpect.EOF:
5248 main.log.error( self.name + ": EOF exception found" )
5249 main.log.error( self.name + ": " + self.handle.before )
5250 main.cleanup()
5251 main.exit()
5252 except Exception:
5253 main.log.exception( self.name + ": Uncaught exception!" )
5254 main.cleanup()
5255 main.exit()
5256
5257 def vplsAddIface( self, network, iface ):
5258 """
5259 CLI command to add an interface to a VPLS network.
5260 Required arguments:
5261 network - Name of the network to add the interface to.
5262 iface - The ONOS name for an interface.
5263 returns:
5264 main.TRUE on success and main.FALSE on failure
5265 """
5266 try:
5267 network = str( network )
5268 iface = str( iface )
5269 cmdStr = "vpls add-if "
5270 cmdStr += network + " " + iface
5271 output = self.sendline( cmdStr )
5272 assert output is not None, "Error in sendline"
5273 assert "Command not found:" not in output, output
5274 assert "Error executing command" not in output, output
5275 assert "already associated to network" not in output, output
5276 assert "Interface cannot be added." not in output, output
5277 return main.TRUE
5278 except AssertionError:
5279 main.log.exception( "" )
5280 return main.FALSE
5281 except TypeError:
5282 main.log.exception( self.name + ": Object not as expected" )
5283 return main.FALSE
5284 except pexpect.EOF:
5285 main.log.error( self.name + ": EOF exception found" )
5286 main.log.error( self.name + ": " + self.handle.before )
5287 main.cleanup()
5288 main.exit()
5289 except Exception:
5290 main.log.exception( self.name + ": Uncaught exception!" )
5291 main.cleanup()
5292 main.exit()
5293
5294 def vplsRemIface( self, network, iface ):
5295 """
5296 CLI command to remove an interface from a VPLS network.
5297 Required arguments:
5298 network - Name of the network to remove the interface from.
5299 iface - Name of the interface to remove.
5300 returns:
5301 main.TRUE on success and main.FALSE on failure
5302 """
5303 try:
5304 iface = str( iface )
5305 cmdStr = "vpls rem-if "
5306 cmdStr += network + " " + iface
5307 output = self.sendline( cmdStr )
5308 assert output is not None, "Error in sendline"
5309 assert "Command not found:" not in output, output
5310 assert "Error executing command" not in output, output
5311 assert "is not configured" 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 vplsClean( self ):
5330 """
5331 Description: Clears the VPLS app configuration.
5332 Returns: main.TRUE on success and main.FALSE on failure
5333 """
5334 try:
5335 cmdStr = "vpls clean"
5336 handle = self.sendline( cmdStr )
5337 assert handle is not None, "Error in sendline"
5338 assert "Command not found:" not in handle, handle
5339 return handle
5340 except AssertionError:
5341 main.log.exception( "" )
5342 return main.FALSE
5343 except TypeError:
5344 main.log.exception( self.name + ": Object not as expected" )
5345 return main.FALSE
5346 except pexpect.EOF:
5347 main.log.error( self.name + ": EOF exception found" )
5348 main.log.error( self.name + ": " + self.handle.before )
5349 main.cleanup()
5350 main.exit()
5351 except Exception:
5352 main.log.exception( self.name + ": Uncaught exception!" )
5353 main.cleanup()
5354 main.exit()
5355
5356 def vplsSetEncap( self, network, encapType ):
5357 """
5358 CLI command to add an interface to a VPLS network.
5359 Required arguments:
5360 network - Name of the network to create.
5361 encapType - Type of encapsulation.
5362 returns:
5363 main.TRUE on success and main.FALSE on failure
5364 """
5365 try:
5366 network = str( network )
5367 encapType = str( encapType ).upper()
5368 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5369 cmdStr = "vpls set-encap "
5370 cmdStr += network + " " + encapType
5371 output = self.sendline( cmdStr )
5372 assert output is not None, "Error in sendline"
5373 assert "Command not found:" not in output, output
5374 assert "Error executing command" not in output, output
5375 assert "already associated to network" not in output, output
5376 assert "Encapsulation type " not in output, output
5377 return main.TRUE
5378 except AssertionError:
5379 main.log.exception( "" )
5380 return main.FALSE
5381 except TypeError:
5382 main.log.exception( self.name + ": Object not as expected" )
5383 return main.FALSE
5384 except pexpect.EOF:
5385 main.log.error( self.name + ": EOF exception found" )
5386 main.log.error( self.name + ": " + self.handle.before )
5387 main.cleanup()
5388 main.exit()
5389 except Exception:
5390 main.log.exception( self.name + ": Uncaught exception!" )
5391 main.cleanup()
5392 main.exit()
5393
5394 def interfaces( self, jsonFormat=True ):
5395 """
5396 Description: Returns result of interfaces command.
5397 Optional:
5398 * jsonFormat: enable json formatting of output
5399 Returns:
5400 The output of the command or None on error.
5401 """
5402 try:
5403 cmdStr = "interfaces"
5404 if jsonFormat:
5405 #raise NotImplementedError
5406 cmdStr += " -j"
5407 handle = self.sendline( cmdStr )
5408 assert handle is not None, "Error in sendline"
5409 assert "Command not found:" not in handle, handle
5410 return handle
5411 except AssertionError:
5412 main.log.exception( "" )
5413 return None
5414 except TypeError:
5415 main.log.exception( self.name + ": Object not as expected" )
5416 return None
5417 except pexpect.EOF:
5418 main.log.error( self.name + ": EOF exception found" )
5419 main.log.error( self.name + ": " + self.handle.before )
5420 main.cleanup()
5421 main.exit()
5422 except NotImplementedError:
5423 main.log.exception( self.name + ": Json output not supported")
5424 return None
5425 except Exception:
5426 main.log.exception( self.name + ": Uncaught exception!" )
5427 main.cleanup()
5428 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005429
5430 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5431 '''
5432 Get the timestamp of searchTerm from karaf log.
5433
5434 Arguments:
5435 splitTerm_before and splitTerm_after:
5436
5437 The terms that split the string that contains the timeStamp of
5438 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5439 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5440 and the splitTerm_after is "x"
5441
5442 others:
5443
5444 plz look at the "logsearch" Function in onosclidriver.py
5445
5446
5447 '''
5448 if logNum < 0:
5449 main.log.error("Get wrong log number ")
5450 return main.ERROR
5451 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5452 if len(lines) == 0:
5453 main.log.warn( "Captured timestamp string is empty" )
5454 return main.ERROR
5455 lines = lines[ 0 ]
5456 try:
5457 assert type(lines) is str
5458 # get the target value
5459 line = lines.split( splitTerm_before )
5460 key = line[ 1 ].split( splitTerm_after )
5461 return int( key[ 0 ] )
5462 except IndexError:
5463 main.log.warn( "Index Error!" )
5464 return main.ERROR
5465 except AssertionError:
5466 main.log.warn( "Search Term Not Found " )
5467 return main.ERROR