blob: e9cf2b17c42942c4256a2a7c2ea4f562c2b1c5d1 [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
kelvin-onlabfb521662015-02-27 09:52:40 -08002646 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002647 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002648
kelvin8ec71442015-01-15 16:57:00 -08002649 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002650 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2651 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002652 match = re.search('id=0x([\da-f]+),', intents)
2653 if match:
2654 tmpId = match.group()[3:-1]
2655 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002656 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002657
Jon Halld4d4b372015-01-28 16:02:41 -08002658 except TypeError:
2659 main.log.exception( self.name + ": Object not as expected" )
2660 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002662 main.log.error( self.name + ": EOF exception found" )
2663 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002664 main.cleanup()
2665 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002667 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002668 main.cleanup()
2669 main.exit()
2670
You Wang3c276252016-09-21 15:21:36 -07002671 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002672 """
2673 Determine the number of flow rules for the given device id that are
2674 in the added state
You Wang3c276252016-09-21 15:21:36 -07002675 Params:
2676 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002677 """
2678 try:
You Wang3c276252016-09-21 15:21:36 -07002679 if core:
2680 cmdStr = "flows any " + str( deviceId ) + " | " +\
2681 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2682 else:
2683 cmdStr = "flows any " + str( deviceId ) + " | " +\
2684 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002685 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002686 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002687 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002688 except AssertionError:
2689 main.log.exception( "" )
2690 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002691 except pexpect.EOF:
2692 main.log.error( self.name + ": EOF exception found" )
2693 main.log.error( self.name + ": " + self.handle.before )
2694 main.cleanup()
2695 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002696 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002697 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002698 main.cleanup()
2699 main.exit()
2700
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002702 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002703 Use 'devices' function to obtain list of all devices
2704 and parse the result to obtain a list of all device
2705 id's. Returns this list. Returns empty list if no
2706 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002707 List is ordered sequentially
2708
andrewonlab3e15ead2014-10-15 14:21:34 -04002709 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002710 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002711 the ids. By obtaining the list of device ids on the fly,
2712 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002713 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002714 try:
kelvin8ec71442015-01-15 16:57:00 -08002715 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 devicesStr = self.devices( jsonFormat=False )
2717 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002718
kelvin-onlabd3b64892015-01-20 13:26:24 -08002719 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002720 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 return idList
kelvin8ec71442015-01-15 16:57:00 -08002722
2723 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002724 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002725 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002726 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002727 # Split list further into arguments before and after string
2728 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002729 # append to idList
2730 for arg in tempList:
2731 idList.append( arg.split( "id=" )[ 1 ] )
2732 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002733
Jon Halld4d4b372015-01-28 16:02:41 -08002734 except TypeError:
2735 main.log.exception( self.name + ": Object not as expected" )
2736 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002738 main.log.error( self.name + ": EOF exception found" )
2739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002740 main.cleanup()
2741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002744 main.cleanup()
2745 main.exit()
2746
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002748 """
andrewonlab7c211572014-10-15 16:45:20 -04002749 Uses 'nodes' function to obtain list of all nodes
2750 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002751 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002752 Returns:
2753 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002754 """
andrewonlab7c211572014-10-15 16:45:20 -04002755 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002756 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002758 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002759 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002760 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002761 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002763 nodesJson = json.loads( nodesStr )
2764 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002765 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002766 except ( TypeError, ValueError ):
2767 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002768 return None
andrewonlab7c211572014-10-15 16:45:20 -04002769 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002770 main.log.error( self.name + ": EOF exception found" )
2771 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002772 main.cleanup()
2773 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002774 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002775 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002776 main.cleanup()
2777 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002778
kelvin-onlabd3b64892015-01-20 13:26:24 -08002779 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002780 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002781 Return the first device from the devices api whose 'id' contains 'dpid'
2782 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002783 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002784 try:
kelvin8ec71442015-01-15 16:57:00 -08002785 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002786 return None
2787 else:
kelvin8ec71442015-01-15 16:57:00 -08002788 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 rawDevices = self.devices()
2790 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002791 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002792 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002793 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2794 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002795 return device
2796 return None
Jon Hallc6793552016-01-19 14:18:37 -08002797 except ( TypeError, ValueError ):
2798 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002799 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002801 main.log.error( self.name + ": EOF exception found" )
2802 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002803 main.cleanup()
2804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002805 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002806 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002807 main.cleanup()
2808 main.exit()
2809
You Wang24139872016-05-03 11:48:47 -07002810 def getTopology( self, topologyOutput ):
2811 """
2812 Definition:
2813 Loads a json topology output
2814 Return:
2815 topology = current ONOS topology
2816 """
2817 import json
2818 try:
2819 # either onos:topology or 'topology' will work in CLI
2820 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002821 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002822 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002823 except ( TypeError, ValueError ):
2824 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2825 return None
You Wang24139872016-05-03 11:48:47 -07002826 except pexpect.EOF:
2827 main.log.error( self.name + ": EOF exception found" )
2828 main.log.error( self.name + ": " + self.handle.before )
2829 main.cleanup()
2830 main.exit()
2831 except Exception:
2832 main.log.exception( self.name + ": Uncaught exception!" )
2833 main.cleanup()
2834 main.exit()
2835
Flavio Castro82ee2f62016-06-07 15:04:12 -07002836 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002837 """
Jon Hallefbd9792015-03-05 16:11:36 -08002838 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002839 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002840 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002841
Flavio Castro82ee2f62016-06-07 15:04:12 -07002842 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002843 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002844 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002845 logLevel = level to log to.
2846 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002847
Jon Hallefbd9792015-03-05 16:11:36 -08002848 Returns: main.TRUE if the number of switches and links are correct,
2849 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002850 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002851 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002852 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002853 try:
You Wang13310252016-07-31 10:56:14 -07002854 summary = self.summary()
2855 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002856 except ( TypeError, ValueError ):
2857 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2858 return main.ERROR
2859 try:
2860 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002861 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002862 return main.ERROR
2863 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002864 # Is the number of switches is what we expected
2865 devices = topology.get( 'devices', False )
2866 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002867 nodes = summary.get( 'nodes', False )
2868 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002869 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002870 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002871 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002873 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2874 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002875 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002876 output = output + "The number of links and switches match "\
2877 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002878 result = main.TRUE
2879 else:
You Wang24139872016-05-03 11:48:47 -07002880 output = output + \
2881 "The number of links and switches does not match " + \
2882 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002883 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002884 output = output + "\n ONOS sees %i devices" % int( devices )
2885 output = output + " (%i expected) " % int( numoswitch )
2886 output = output + "and %i links " % int( links )
2887 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002888 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002889 output = output + "and %i controllers " % int( nodes )
2890 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002892 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002893 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002894 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002895 else:
You Wang24139872016-05-03 11:48:47 -07002896 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002897 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002898 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002899 main.log.error( self.name + ": EOF exception found" )
2900 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002901 main.cleanup()
2902 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002903 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002904 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002905 main.cleanup()
2906 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002907
kelvin-onlabd3b64892015-01-20 13:26:24 -08002908 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002909 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002910 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002911 deviceId must be the id of a device as seen in the onos devices command
2912 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002913 role must be either master, standby, or none
2914
Jon Halle3f39ff2015-01-13 11:50:53 -08002915 Returns:
2916 main.TRUE or main.FALSE based on argument verification and
2917 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002918 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002919 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002920 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002921 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 cmdStr = "device-role " +\
2923 str( deviceId ) + " " +\
2924 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002925 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002927 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 if re.search( "Error", handle ):
2929 # end color output to escape any colours
2930 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002931 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002932 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002933 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002934 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002935 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 main.log.error( "Invalid 'role' given to device_role(). " +
2937 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002938 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002939 except AssertionError:
2940 main.log.exception( "" )
2941 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002942 except TypeError:
2943 main.log.exception( self.name + ": Object not as expected" )
2944 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002946 main.log.error( self.name + ": EOF exception found" )
2947 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002948 main.cleanup()
2949 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002950 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002951 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002952 main.cleanup()
2953 main.exit()
2954
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002956 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002957 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002958 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002959 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002960 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002961 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002962 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002963 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002964 cmdStr += " -j"
2965 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002966 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002967 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002968 except AssertionError:
2969 main.log.exception( "" )
2970 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002971 except TypeError:
2972 main.log.exception( self.name + ": Object not as expected" )
2973 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002974 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002977 main.cleanup()
2978 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002979 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002980 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002981 main.cleanup()
2982 main.exit()
2983
kelvin-onlabd3b64892015-01-20 13:26:24 -08002984 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002985 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002986 CLI command to get the current leader for the Election test application
2987 NOTE: Requires installation of the onos-app-election feature
2988 Returns: Node IP of the leader if one exists
2989 None if none exists
2990 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 """
Jon Hall94fd0472014-12-08 11:52:42 -08002992 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 cmdStr = "election-test-leader"
2994 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002995 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002996 # Leader
2997 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002998 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002999 nodeSearch = re.search( leaderPattern, response )
3000 if nodeSearch:
3001 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003002 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003004 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 # no leader
3006 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003007 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003008 nullSearch = re.search( nullPattern, response )
3009 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003010 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003011 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003012 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003013 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003014 main.log.error( "Error in electionTestLeader on " + self.name +
3015 ": " + "unexpected response" )
3016 main.log.error( repr( response ) )
3017 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003018 except AssertionError:
3019 main.log.exception( "" )
3020 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003021 except TypeError:
3022 main.log.exception( self.name + ": Object not as expected" )
3023 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003024 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003025 main.log.error( self.name + ": EOF exception found" )
3026 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003027 main.cleanup()
3028 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003029 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003030 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003031 main.cleanup()
3032 main.exit()
3033
kelvin-onlabd3b64892015-01-20 13:26:24 -08003034 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003035 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003036 CLI command to run for leadership of the Election test application.
3037 NOTE: Requires installation of the onos-app-election feature
3038 Returns: Main.TRUE on success
3039 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 """
Jon Hall94fd0472014-12-08 11:52:42 -08003041 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003042 cmdStr = "election-test-run"
3043 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003044 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003045 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003046 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003048 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003049 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003050 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003051 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003052 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003053 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003054 main.log.error( "Error in electionTestRun on " + self.name +
3055 ": " + "unexpected response" )
3056 main.log.error( repr( response ) )
3057 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003058 except AssertionError:
3059 main.log.exception( "" )
3060 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003061 except TypeError:
3062 main.log.exception( self.name + ": Object not as expected" )
3063 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003065 main.log.error( self.name + ": EOF exception found" )
3066 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003067 main.cleanup()
3068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003070 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003071 main.cleanup()
3072 main.exit()
3073
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003075 """
Jon Hall94fd0472014-12-08 11:52:42 -08003076 * CLI command to withdraw the local node from leadership election for
3077 * the Election test application.
3078 #NOTE: Requires installation of the onos-app-election feature
3079 Returns: Main.TRUE on success
3080 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003081 """
Jon Hall94fd0472014-12-08 11:52:42 -08003082 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003083 cmdStr = "election-test-withdraw"
3084 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003085 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003086 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003087 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003088 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003089 if re.search( successPattern, response ):
3090 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003091 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003092 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003093 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003094 main.log.error( "Error in electionTestWithdraw on " +
3095 self.name + ": " + "unexpected response" )
3096 main.log.error( repr( response ) )
3097 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003098 except AssertionError:
3099 main.log.exception( "" )
3100 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003101 except TypeError:
3102 main.log.exception( self.name + ": Object not as expected" )
3103 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003104 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003105 main.log.error( self.name + ": EOF exception found" )
3106 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003107 main.cleanup()
3108 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003110 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003111 main.cleanup()
3112 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003113
kelvin8ec71442015-01-15 16:57:00 -08003114 def getDevicePortsEnabledCount( self, dpid ):
3115 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003116 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003117 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003118 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003119 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3121 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003122 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003123 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003124 if re.search( "No such device", output ):
3125 main.log.error( "Error in getting ports" )
3126 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003127 return output
Jon Hallc6793552016-01-19 14:18:37 -08003128 except AssertionError:
3129 main.log.exception( "" )
3130 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003131 except TypeError:
3132 main.log.exception( self.name + ": Object not as expected" )
3133 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003134 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003135 main.log.error( self.name + ": EOF exception found" )
3136 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 main.cleanup()
3138 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003140 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 main.cleanup()
3142 main.exit()
3143
kelvin8ec71442015-01-15 16:57:00 -08003144 def getDeviceLinksActiveCount( self, dpid ):
3145 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003146 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003147 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003148 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003149 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003150 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3151 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003152 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003153 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003154 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003155 main.log.error( "Error in getting ports " )
3156 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003157 return output
Jon Hallc6793552016-01-19 14:18:37 -08003158 except AssertionError:
3159 main.log.exception( "" )
3160 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003161 except TypeError:
3162 main.log.exception( self.name + ": Object not as expected" )
3163 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003165 main.log.error( self.name + ": EOF exception found" )
3166 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167 main.cleanup()
3168 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003169 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003170 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003171 main.cleanup()
3172 main.exit()
3173
kelvin8ec71442015-01-15 16:57:00 -08003174 def getAllIntentIds( self ):
3175 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003176 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003177 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003178 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003179 cmdStr = "onos:intents | grep id="
3180 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003181 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003182 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003183 if re.search( "Error", output ):
3184 main.log.error( "Error in getting ports" )
3185 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003186 return output
Jon Hallc6793552016-01-19 14:18:37 -08003187 except AssertionError:
3188 main.log.exception( "" )
3189 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003190 except TypeError:
3191 main.log.exception( self.name + ": Object not as expected" )
3192 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003193 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003194 main.log.error( self.name + ": EOF exception found" )
3195 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003196 main.cleanup()
3197 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003198 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003199 main.log.exception( self.name + ": Uncaught exception!" )
3200 main.cleanup()
3201 main.exit()
3202
Jon Hall73509952015-02-24 16:42:56 -08003203 def intentSummary( self ):
3204 """
Jon Hallefbd9792015-03-05 16:11:36 -08003205 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003206 """
3207 try:
3208 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003209 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003210 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003211 states.append( intent.get( 'state', None ) )
3212 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003213 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003214 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003215 except ( TypeError, ValueError ):
3216 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003217 return None
3218 except pexpect.EOF:
3219 main.log.error( self.name + ": EOF exception found" )
3220 main.log.error( self.name + ": " + self.handle.before )
3221 main.cleanup()
3222 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003223 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003224 main.log.exception( self.name + ": Uncaught exception!" )
3225 main.cleanup()
3226 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003227
Jon Hall61282e32015-03-19 11:34:11 -07003228 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003229 """
3230 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003231 Optional argument:
3232 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003233 """
Jon Hall63604932015-02-26 17:09:50 -08003234 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003235 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003236 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003237 cmdStr += " -j"
3238 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003239 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003240 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003241 return output
Jon Hallc6793552016-01-19 14:18:37 -08003242 except AssertionError:
3243 main.log.exception( "" )
3244 return None
Jon Hall63604932015-02-26 17:09:50 -08003245 except TypeError:
3246 main.log.exception( self.name + ": Object not as expected" )
3247 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003248 except pexpect.EOF:
3249 main.log.error( self.name + ": EOF exception found" )
3250 main.log.error( self.name + ": " + self.handle.before )
3251 main.cleanup()
3252 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003253 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003254 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003255 main.cleanup()
3256 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003257
acsmarsa4a4d1e2015-07-10 16:01:24 -07003258 def leaderCandidates( self, jsonFormat=True ):
3259 """
3260 Returns the output of the leaders -c command.
3261 Optional argument:
3262 * jsonFormat - boolean indicating if you want output in json
3263 """
3264 try:
3265 cmdStr = "onos:leaders -c"
3266 if jsonFormat:
3267 cmdStr += " -j"
3268 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003269 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003270 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003271 return output
Jon Hallc6793552016-01-19 14:18:37 -08003272 except AssertionError:
3273 main.log.exception( "" )
3274 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003275 except TypeError:
3276 main.log.exception( self.name + ": Object not as expected" )
3277 return None
3278 except pexpect.EOF:
3279 main.log.error( self.name + ": EOF exception found" )
3280 main.log.error( self.name + ": " + self.handle.before )
3281 main.cleanup()
3282 main.exit()
3283 except Exception:
3284 main.log.exception( self.name + ": Uncaught exception!" )
3285 main.cleanup()
3286 main.exit()
3287
Jon Hallc6793552016-01-19 14:18:37 -08003288 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003289 """
3290 Returns a list in format [leader,candidate1,candidate2,...] for a given
3291 topic parameter and an empty list if the topic doesn't exist
3292 If no leader is elected leader in the returned list will be "none"
3293 Returns None if there is a type error processing the json object
3294 """
3295 try:
Jon Hall6e709752016-02-01 13:38:46 -08003296 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003297 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003298 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003299 assert "Command not found:" not in rawOutput, rawOutput
3300 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003301 results = []
3302 for dict in output:
3303 if dict["topic"] == topic:
3304 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003305 candidates = re.split( ", ", dict["candidates"][1:-1] )
3306 results.append( leader )
3307 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003308 return results
Jon Hallc6793552016-01-19 14:18:37 -08003309 except AssertionError:
3310 main.log.exception( "" )
3311 return None
3312 except ( TypeError, ValueError ):
3313 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003314 return None
3315 except pexpect.EOF:
3316 main.log.error( self.name + ": EOF exception found" )
3317 main.log.error( self.name + ": " + self.handle.before )
3318 main.cleanup()
3319 main.exit()
3320 except Exception:
3321 main.log.exception( self.name + ": Uncaught exception!" )
3322 main.cleanup()
3323 main.exit()
3324
Jon Hall61282e32015-03-19 11:34:11 -07003325 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003326 """
3327 Returns the output of the intent Pending map.
3328 """
Jon Hall63604932015-02-26 17:09:50 -08003329 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003330 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003331 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 cmdStr += " -j"
3333 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003334 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003335 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003336 return output
Jon Hallc6793552016-01-19 14:18:37 -08003337 except AssertionError:
3338 main.log.exception( "" )
3339 return None
Jon Hall63604932015-02-26 17:09:50 -08003340 except TypeError:
3341 main.log.exception( self.name + ": Object not as expected" )
3342 return None
3343 except pexpect.EOF:
3344 main.log.error( self.name + ": EOF exception found" )
3345 main.log.error( self.name + ": " + self.handle.before )
3346 main.cleanup()
3347 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003348 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003349 main.log.exception( self.name + ": Uncaught exception!" )
3350 main.cleanup()
3351 main.exit()
3352
Jon Hall2c8959e2016-12-16 12:17:34 -08003353 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003354 """
3355 Returns the output of the raft partitions command for ONOS.
3356 """
Jon Hall61282e32015-03-19 11:34:11 -07003357 # Sample JSON
3358 # {
3359 # "leader": "tcp://10.128.30.11:7238",
3360 # "members": [
3361 # "tcp://10.128.30.11:7238",
3362 # "tcp://10.128.30.17:7238",
3363 # "tcp://10.128.30.13:7238",
3364 # ],
3365 # "name": "p1",
3366 # "term": 3
3367 # },
Jon Hall63604932015-02-26 17:09:50 -08003368 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003369 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003370 if candidates:
3371 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003372 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 cmdStr += " -j"
3374 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003375 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003376 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003377 return output
Jon Hallc6793552016-01-19 14:18:37 -08003378 except AssertionError:
3379 main.log.exception( "" )
3380 return None
Jon Hall63604932015-02-26 17:09:50 -08003381 except TypeError:
3382 main.log.exception( self.name + ": Object not as expected" )
3383 return None
3384 except pexpect.EOF:
3385 main.log.error( self.name + ": EOF exception found" )
3386 main.log.error( self.name + ": " + self.handle.before )
3387 main.cleanup()
3388 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003389 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003390 main.log.exception( self.name + ": Uncaught exception!" )
3391 main.cleanup()
3392 main.exit()
3393
Jon Halle9f909e2016-09-23 10:43:12 -07003394 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003395 """
3396 Returns the output of the apps command for ONOS. This command lists
3397 information about installed ONOS applications
3398 """
3399 # Sample JSON object
3400 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3401 # "description":"ONOS OpenFlow protocol southbound providers",
3402 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3403 # "features":"[onos-openflow]","state":"ACTIVE"}]
3404 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003405 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003406 if summary:
3407 cmdStr += " -s"
3408 if active:
3409 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003410 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003411 cmdStr += " -j"
3412 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003413 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003414 assert "Command not found:" not in output, output
3415 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003416 return output
Jon Hallbe379602015-03-24 13:39:32 -07003417 # FIXME: look at specific exceptions/Errors
3418 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003419 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003420 return None
3421 except TypeError:
3422 main.log.exception( self.name + ": Object not as expected" )
3423 return None
3424 except pexpect.EOF:
3425 main.log.error( self.name + ": EOF exception found" )
3426 main.log.error( self.name + ": " + self.handle.before )
3427 main.cleanup()
3428 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003429 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003430 main.log.exception( self.name + ": Uncaught exception!" )
3431 main.cleanup()
3432 main.exit()
3433
Jon Hall146f1522015-03-24 15:33:24 -07003434 def appStatus( self, appName ):
3435 """
3436 Uses the onos:apps cli command to return the status of an application.
3437 Returns:
3438 "ACTIVE" - If app is installed and activated
3439 "INSTALLED" - If app is installed and deactivated
3440 "UNINSTALLED" - If app is not installed
3441 None - on error
3442 """
Jon Hall146f1522015-03-24 15:33:24 -07003443 try:
3444 if not isinstance( appName, types.StringType ):
3445 main.log.error( self.name + ".appStatus(): appName must be" +
3446 " a string" )
3447 return None
3448 output = self.apps( jsonFormat=True )
3449 appsJson = json.loads( output )
3450 state = None
3451 for app in appsJson:
3452 if appName == app.get('name'):
3453 state = app.get('state')
3454 break
3455 if state == "ACTIVE" or state == "INSTALLED":
3456 return state
3457 elif state is None:
3458 return "UNINSTALLED"
3459 elif state:
3460 main.log.error( "Unexpected state from 'onos:apps': " +
3461 str( state ) )
3462 return state
Jon Hallc6793552016-01-19 14:18:37 -08003463 except ( TypeError, ValueError ):
3464 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003465 return None
3466 except pexpect.EOF:
3467 main.log.error( self.name + ": EOF exception found" )
3468 main.log.error( self.name + ": " + self.handle.before )
3469 main.cleanup()
3470 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003471 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003472 main.log.exception( self.name + ": Uncaught exception!" )
3473 main.cleanup()
3474 main.exit()
3475
Jon Hallbe379602015-03-24 13:39:32 -07003476 def app( self, appName, option ):
3477 """
3478 Interacts with the app command for ONOS. This command manages
3479 application inventory.
3480 """
Jon Hallbe379602015-03-24 13:39:32 -07003481 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003482 # Validate argument types
3483 valid = True
3484 if not isinstance( appName, types.StringType ):
3485 main.log.error( self.name + ".app(): appName must be a " +
3486 "string" )
3487 valid = False
3488 if not isinstance( option, types.StringType ):
3489 main.log.error( self.name + ".app(): option must be a string" )
3490 valid = False
3491 if not valid:
3492 return main.FALSE
3493 # Validate Option
3494 option = option.lower()
3495 # NOTE: Install may become a valid option
3496 if option == "activate":
3497 pass
3498 elif option == "deactivate":
3499 pass
3500 elif option == "uninstall":
3501 pass
3502 else:
3503 # Invalid option
3504 main.log.error( "The ONOS app command argument only takes " +
3505 "the values: (activate|deactivate|uninstall)" +
3506 "; was given '" + option + "'")
3507 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003508 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003509 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003510 if "Error executing command" in output:
3511 main.log.error( "Error in processing onos:app command: " +
3512 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003513 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003514 elif "No such application" in output:
3515 main.log.error( "The application '" + appName +
3516 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003517 return main.FALSE
3518 elif "Command not found:" in output:
3519 main.log.error( "Error in processing onos:app command: " +
3520 str( output ) )
3521 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003522 elif "Unsupported command:" in output:
3523 main.log.error( "Incorrect command given to 'app': " +
3524 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003525 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003526 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003527 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003528 return main.TRUE
3529 except TypeError:
3530 main.log.exception( self.name + ": Object not as expected" )
3531 return main.ERROR
3532 except pexpect.EOF:
3533 main.log.error( self.name + ": EOF exception found" )
3534 main.log.error( self.name + ": " + self.handle.before )
3535 main.cleanup()
3536 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003537 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003538 main.log.exception( self.name + ": Uncaught exception!" )
3539 main.cleanup()
3540 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003541
Jon Hallbd16b922015-03-26 17:53:15 -07003542 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003543 """
3544 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003545 appName is the hierarchical app name, not the feature name
3546 If check is True, method will check the status of the app after the
3547 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003548 Returns main.TRUE if the command was successfully sent
3549 main.FALSE if the cli responded with an error or given
3550 incorrect input
3551 """
3552 try:
3553 if not isinstance( appName, types.StringType ):
3554 main.log.error( self.name + ".activateApp(): appName must be" +
3555 " a string" )
3556 return main.FALSE
3557 status = self.appStatus( appName )
3558 if status == "INSTALLED":
3559 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003560 if check and response == main.TRUE:
3561 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003562 status = self.appStatus( appName )
3563 if status == "ACTIVE":
3564 return main.TRUE
3565 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003566 main.log.debug( "The state of application " +
3567 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003568 time.sleep( 1 )
3569 return main.FALSE
3570 else: # not 'check' or command didn't succeed
3571 return response
Jon Hall146f1522015-03-24 15:33:24 -07003572 elif status == "ACTIVE":
3573 return main.TRUE
3574 elif status == "UNINSTALLED":
3575 main.log.error( self.name + ": Tried to activate the " +
3576 "application '" + appName + "' which is not " +
3577 "installed." )
3578 else:
3579 main.log.error( "Unexpected return value from appStatus: " +
3580 str( status ) )
3581 return main.ERROR
3582 except TypeError:
3583 main.log.exception( self.name + ": Object not as expected" )
3584 return main.ERROR
3585 except pexpect.EOF:
3586 main.log.error( self.name + ": EOF exception found" )
3587 main.log.error( self.name + ": " + self.handle.before )
3588 main.cleanup()
3589 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003590 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003591 main.log.exception( self.name + ": Uncaught exception!" )
3592 main.cleanup()
3593 main.exit()
3594
Jon Hallbd16b922015-03-26 17:53:15 -07003595 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003596 """
3597 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003598 appName is the hierarchical app name, not the feature name
3599 If check is True, method will check the status of the app after the
3600 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003601 Returns main.TRUE if the command was successfully sent
3602 main.FALSE if the cli responded with an error or given
3603 incorrect input
3604 """
3605 try:
3606 if not isinstance( appName, types.StringType ):
3607 main.log.error( self.name + ".deactivateApp(): appName must " +
3608 "be a string" )
3609 return main.FALSE
3610 status = self.appStatus( appName )
3611 if status == "INSTALLED":
3612 return main.TRUE
3613 elif status == "ACTIVE":
3614 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003615 if check and response == main.TRUE:
3616 for i in range(10): # try 10 times then give up
3617 status = self.appStatus( appName )
3618 if status == "INSTALLED":
3619 return main.TRUE
3620 else:
3621 time.sleep( 1 )
3622 return main.FALSE
3623 else: # not check or command didn't succeed
3624 return response
Jon Hall146f1522015-03-24 15:33:24 -07003625 elif status == "UNINSTALLED":
3626 main.log.warn( self.name + ": Tried to deactivate the " +
3627 "application '" + appName + "' which is not " +
3628 "installed." )
3629 return main.TRUE
3630 else:
3631 main.log.error( "Unexpected return value from appStatus: " +
3632 str( status ) )
3633 return main.ERROR
3634 except TypeError:
3635 main.log.exception( self.name + ": Object not as expected" )
3636 return main.ERROR
3637 except pexpect.EOF:
3638 main.log.error( self.name + ": EOF exception found" )
3639 main.log.error( self.name + ": " + self.handle.before )
3640 main.cleanup()
3641 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003642 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003643 main.log.exception( self.name + ": Uncaught exception!" )
3644 main.cleanup()
3645 main.exit()
3646
Jon Hallbd16b922015-03-26 17:53:15 -07003647 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003648 """
3649 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003650 appName is the hierarchical app name, not the feature name
3651 If check is True, method will check the status of the app after the
3652 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003653 Returns main.TRUE if the command was successfully sent
3654 main.FALSE if the cli responded with an error or given
3655 incorrect input
3656 """
3657 # TODO: check with Thomas about the state machine for apps
3658 try:
3659 if not isinstance( appName, types.StringType ):
3660 main.log.error( self.name + ".uninstallApp(): appName must " +
3661 "be a string" )
3662 return main.FALSE
3663 status = self.appStatus( appName )
3664 if status == "INSTALLED":
3665 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003666 if check and response == main.TRUE:
3667 for i in range(10): # try 10 times then give up
3668 status = self.appStatus( appName )
3669 if status == "UNINSTALLED":
3670 return main.TRUE
3671 else:
3672 time.sleep( 1 )
3673 return main.FALSE
3674 else: # not check or command didn't succeed
3675 return response
Jon Hall146f1522015-03-24 15:33:24 -07003676 elif status == "ACTIVE":
3677 main.log.warn( self.name + ": Tried to uninstall the " +
3678 "application '" + appName + "' which is " +
3679 "currently active." )
3680 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003681 if check and response == main.TRUE:
3682 for i in range(10): # try 10 times then give up
3683 status = self.appStatus( appName )
3684 if status == "UNINSTALLED":
3685 return main.TRUE
3686 else:
3687 time.sleep( 1 )
3688 return main.FALSE
3689 else: # not check or command didn't succeed
3690 return response
Jon Hall146f1522015-03-24 15:33:24 -07003691 elif status == "UNINSTALLED":
3692 return main.TRUE
3693 else:
3694 main.log.error( "Unexpected return value from appStatus: " +
3695 str( status ) )
3696 return main.ERROR
3697 except TypeError:
3698 main.log.exception( self.name + ": Object not as expected" )
3699 return main.ERROR
3700 except pexpect.EOF:
3701 main.log.error( self.name + ": EOF exception found" )
3702 main.log.error( self.name + ": " + self.handle.before )
3703 main.cleanup()
3704 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003705 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003706 main.log.exception( self.name + ": Uncaught exception!" )
3707 main.cleanup()
3708 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003709
3710 def appIDs( self, jsonFormat=True ):
3711 """
3712 Show the mappings between app id and app names given by the 'app-ids'
3713 cli command
3714 """
3715 try:
3716 cmdStr = "app-ids"
3717 if jsonFormat:
3718 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003719 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003720 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003721 assert "Command not found:" not in output, output
3722 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003723 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003724 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003725 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003726 return None
3727 except TypeError:
3728 main.log.exception( self.name + ": Object not as expected" )
3729 return None
3730 except pexpect.EOF:
3731 main.log.error( self.name + ": EOF exception found" )
3732 main.log.error( self.name + ": " + self.handle.before )
3733 main.cleanup()
3734 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003735 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003736 main.log.exception( self.name + ": Uncaught exception!" )
3737 main.cleanup()
3738 main.exit()
3739
3740 def appToIDCheck( self ):
3741 """
3742 This method will check that each application's ID listed in 'apps' is
3743 the same as the ID listed in 'app-ids'. The check will also check that
3744 there are no duplicate IDs issued. Note that an app ID should be
3745 a globaly unique numerical identifier for app/app-like features. Once
3746 an ID is registered, the ID is never freed up so that if an app is
3747 reinstalled it will have the same ID.
3748
3749 Returns: main.TRUE if the check passes and
3750 main.FALSE if the check fails or
3751 main.ERROR if there is some error in processing the test
3752 """
3753 try:
Jon Hall390696c2015-05-05 17:13:41 -07003754 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003755 rawJson = self.appIDs( jsonFormat=True )
3756 if rawJson:
3757 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003758 else:
Jon Hallc6793552016-01-19 14:18:37 -08003759 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003760 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003761 rawJson = self.apps( jsonFormat=True )
3762 if rawJson:
3763 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003764 else:
Jon Hallc6793552016-01-19 14:18:37 -08003765 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003766 bail = True
3767 if bail:
3768 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003769 result = main.TRUE
3770 for app in apps:
3771 appID = app.get( 'id' )
3772 if appID is None:
3773 main.log.error( "Error parsing app: " + str( app ) )
3774 result = main.FALSE
3775 appName = app.get( 'name' )
3776 if appName is None:
3777 main.log.error( "Error parsing app: " + str( app ) )
3778 result = main.FALSE
3779 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003780 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003781 # main.log.debug( "Comparing " + str( app ) + " to " +
3782 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003783 if not current: # if ids doesn't have this id
3784 result = main.FALSE
3785 main.log.error( "'app-ids' does not have the ID for " +
3786 str( appName ) + " that apps does." )
3787 elif len( current ) > 1:
3788 # there is more than one app with this ID
3789 result = main.FALSE
3790 # We will log this later in the method
3791 elif not current[0][ 'name' ] == appName:
3792 currentName = current[0][ 'name' ]
3793 result = main.FALSE
3794 main.log.error( "'app-ids' has " + str( currentName ) +
3795 " registered under id:" + str( appID ) +
3796 " but 'apps' has " + str( appName ) )
3797 else:
3798 pass # id and name match!
3799 # now make sure that app-ids has no duplicates
3800 idsList = []
3801 namesList = []
3802 for item in ids:
3803 idsList.append( item[ 'id' ] )
3804 namesList.append( item[ 'name' ] )
3805 if len( idsList ) != len( set( idsList ) ) or\
3806 len( namesList ) != len( set( namesList ) ):
3807 main.log.error( "'app-ids' has some duplicate entries: \n"
3808 + json.dumps( ids,
3809 sort_keys=True,
3810 indent=4,
3811 separators=( ',', ': ' ) ) )
3812 result = main.FALSE
3813 return result
Jon Hallc6793552016-01-19 14:18:37 -08003814 except ( TypeError, ValueError ):
3815 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003816 return main.ERROR
3817 except pexpect.EOF:
3818 main.log.error( self.name + ": EOF exception found" )
3819 main.log.error( self.name + ": " + self.handle.before )
3820 main.cleanup()
3821 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003822 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003823 main.log.exception( self.name + ": Uncaught exception!" )
3824 main.cleanup()
3825 main.exit()
3826
Jon Hallfb760a02015-04-13 15:35:03 -07003827 def getCfg( self, component=None, propName=None, short=False,
3828 jsonFormat=True ):
3829 """
3830 Get configuration settings from onos cli
3831 Optional arguments:
3832 component - Optionally only list configurations for a specific
3833 component. If None, all components with configurations
3834 are displayed. Case Sensitive string.
3835 propName - If component is specified, propName option will show
3836 only this specific configuration from that component.
3837 Case Sensitive string.
3838 jsonFormat - Returns output as json. Note that this will override
3839 the short option
3840 short - Short, less verbose, version of configurations.
3841 This is overridden by the json option
3842 returns:
3843 Output from cli as a string or None on error
3844 """
3845 try:
3846 baseStr = "cfg"
3847 cmdStr = " get"
3848 componentStr = ""
3849 if component:
3850 componentStr += " " + component
3851 if propName:
3852 componentStr += " " + propName
3853 if jsonFormat:
3854 baseStr += " -j"
3855 elif short:
3856 baseStr += " -s"
3857 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003858 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003859 assert "Command not found:" not in output, output
3860 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003861 return output
3862 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003863 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003864 return None
3865 except TypeError:
3866 main.log.exception( self.name + ": Object not as expected" )
3867 return None
3868 except pexpect.EOF:
3869 main.log.error( self.name + ": EOF exception found" )
3870 main.log.error( self.name + ": " + self.handle.before )
3871 main.cleanup()
3872 main.exit()
3873 except Exception:
3874 main.log.exception( self.name + ": Uncaught exception!" )
3875 main.cleanup()
3876 main.exit()
3877
3878 def setCfg( self, component, propName, value=None, check=True ):
3879 """
3880 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003881 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003882 component - The case sensitive name of the component whose
3883 property is to be set
3884 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003885 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003886 value - The value to set the property to. If None, will unset the
3887 property and revert it to it's default value(if applicable)
3888 check - Boolean, Check whether the option was successfully set this
3889 only applies when a value is given.
3890 returns:
3891 main.TRUE on success or main.FALSE on failure. If check is False,
3892 will return main.TRUE unless there is an error
3893 """
3894 try:
3895 baseStr = "cfg"
3896 cmdStr = " set " + str( component ) + " " + str( propName )
3897 if value is not None:
3898 cmdStr += " " + str( value )
3899 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003900 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003901 assert "Command not found:" not in output, output
3902 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003903 if value and check:
3904 results = self.getCfg( component=str( component ),
3905 propName=str( propName ),
3906 jsonFormat=True )
3907 # Check if current value is what we just set
3908 try:
3909 jsonOutput = json.loads( results )
3910 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003911 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003912 main.log.exception( "Error parsing cfg output" )
3913 main.log.error( "output:" + repr( results ) )
3914 return main.FALSE
3915 if current == str( value ):
3916 return main.TRUE
3917 return main.FALSE
3918 return main.TRUE
3919 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003920 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003921 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003922 except ( TypeError, ValueError ):
3923 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003924 return main.FALSE
3925 except pexpect.EOF:
3926 main.log.error( self.name + ": EOF exception found" )
3927 main.log.error( self.name + ": " + self.handle.before )
3928 main.cleanup()
3929 main.exit()
3930 except Exception:
3931 main.log.exception( self.name + ": Uncaught exception!" )
3932 main.cleanup()
3933 main.exit()
3934
Jon Hall390696c2015-05-05 17:13:41 -07003935 def setTestAdd( self, setName, values ):
3936 """
3937 CLI command to add elements to a distributed set.
3938 Arguments:
3939 setName - The name of the set to add to.
3940 values - The value(s) to add to the set, space seperated.
3941 Example usages:
3942 setTestAdd( "set1", "a b c" )
3943 setTestAdd( "set2", "1" )
3944 returns:
3945 main.TRUE on success OR
3946 main.FALSE if elements were already in the set OR
3947 main.ERROR on error
3948 """
3949 try:
3950 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3951 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003952 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003953 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003954 try:
3955 # TODO: Maybe make this less hardcoded
3956 # ConsistentMap Exceptions
3957 assert "org.onosproject.store.service" not in output
3958 # Node not leader
3959 assert "java.lang.IllegalStateException" not in output
3960 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003961 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003962 "command: " + str( output ) )
3963 retryTime = 30 # Conservative time, given by Madan
3964 main.log.info( "Waiting " + str( retryTime ) +
3965 "seconds before retrying." )
3966 time.sleep( retryTime ) # Due to change in mastership
3967 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003968 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003969 assert "Error executing command" not in output
3970 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3971 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3972 main.log.info( self.name + ": " + output )
3973 if re.search( positiveMatch, output):
3974 return main.TRUE
3975 elif re.search( negativeMatch, output):
3976 return main.FALSE
3977 else:
3978 main.log.error( self.name + ": setTestAdd did not" +
3979 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003980 main.log.debug( self.name + " actual: " + repr( output ) )
3981 return main.ERROR
3982 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003983 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003984 return main.ERROR
3985 except TypeError:
3986 main.log.exception( self.name + ": Object not as expected" )
3987 return main.ERROR
3988 except pexpect.EOF:
3989 main.log.error( self.name + ": EOF exception found" )
3990 main.log.error( self.name + ": " + self.handle.before )
3991 main.cleanup()
3992 main.exit()
3993 except Exception:
3994 main.log.exception( self.name + ": Uncaught exception!" )
3995 main.cleanup()
3996 main.exit()
3997
3998 def setTestRemove( self, setName, values, clear=False, retain=False ):
3999 """
4000 CLI command to remove elements from a distributed set.
4001 Required arguments:
4002 setName - The name of the set to remove from.
4003 values - The value(s) to remove from the set, space seperated.
4004 Optional arguments:
4005 clear - Clear all elements from the set
4006 retain - Retain only the given values. (intersection of the
4007 original set and the given set)
4008 returns:
4009 main.TRUE on success OR
4010 main.FALSE if the set was not changed OR
4011 main.ERROR on error
4012 """
4013 try:
4014 cmdStr = "set-test-remove "
4015 if clear:
4016 cmdStr += "-c " + str( setName )
4017 elif retain:
4018 cmdStr += "-r " + str( setName ) + " " + str( values )
4019 else:
4020 cmdStr += str( setName ) + " " + str( values )
4021 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004022 try:
Jon Halla495f562016-05-16 18:03:26 -07004023 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004024 # TODO: Maybe make this less hardcoded
4025 # ConsistentMap Exceptions
4026 assert "org.onosproject.store.service" not in output
4027 # Node not leader
4028 assert "java.lang.IllegalStateException" not in output
4029 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004030 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004031 "command: " + str( output ) )
4032 retryTime = 30 # Conservative time, given by Madan
4033 main.log.info( "Waiting " + str( retryTime ) +
4034 "seconds before retrying." )
4035 time.sleep( retryTime ) # Due to change in mastership
4036 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004037 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004038 assert "Command not found:" not in output, output
4039 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004040 main.log.info( self.name + ": " + output )
4041 if clear:
4042 pattern = "Set " + str( setName ) + " cleared"
4043 if re.search( pattern, output ):
4044 return main.TRUE
4045 elif retain:
4046 positivePattern = str( setName ) + " was pruned to contain " +\
4047 "only elements of set \[(.*)\]"
4048 negativePattern = str( setName ) + " was not changed by " +\
4049 "retaining only elements of the set " +\
4050 "\[(.*)\]"
4051 if re.search( positivePattern, output ):
4052 return main.TRUE
4053 elif re.search( negativePattern, output ):
4054 return main.FALSE
4055 else:
4056 positivePattern = "\[(.*)\] was removed from the set " +\
4057 str( setName )
4058 if ( len( values.split() ) == 1 ):
4059 negativePattern = "\[(.*)\] was not in set " +\
4060 str( setName )
4061 else:
4062 negativePattern = "No element of \[(.*)\] was in set " +\
4063 str( setName )
4064 if re.search( positivePattern, output ):
4065 return main.TRUE
4066 elif re.search( negativePattern, output ):
4067 return main.FALSE
4068 main.log.error( self.name + ": setTestRemove did not" +
4069 " match expected output" )
4070 main.log.debug( self.name + " expected: " + pattern )
4071 main.log.debug( self.name + " actual: " + repr( output ) )
4072 return main.ERROR
4073 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004074 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004075 return main.ERROR
4076 except TypeError:
4077 main.log.exception( self.name + ": Object not as expected" )
4078 return main.ERROR
4079 except pexpect.EOF:
4080 main.log.error( self.name + ": EOF exception found" )
4081 main.log.error( self.name + ": " + self.handle.before )
4082 main.cleanup()
4083 main.exit()
4084 except Exception:
4085 main.log.exception( self.name + ": Uncaught exception!" )
4086 main.cleanup()
4087 main.exit()
4088
4089 def setTestGet( self, setName, values="" ):
4090 """
4091 CLI command to get the elements in a distributed set.
4092 Required arguments:
4093 setName - The name of the set to remove from.
4094 Optional arguments:
4095 values - The value(s) to check if in the set, space seperated.
4096 returns:
4097 main.ERROR on error OR
4098 A list of elements in the set if no optional arguments are
4099 supplied OR
4100 A tuple containing the list then:
4101 main.FALSE if the given values are not in the set OR
4102 main.TRUE if the given values are in the set OR
4103 """
4104 try:
4105 values = str( values ).strip()
4106 setName = str( setName ).strip()
4107 length = len( values.split() )
4108 containsCheck = None
4109 # Patterns to match
4110 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004111 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004112 containsTrue = "Set " + setName + " contains the value " + values
4113 containsFalse = "Set " + setName + " did not contain the value " +\
4114 values
4115 containsAllTrue = "Set " + setName + " contains the the subset " +\
4116 setPattern
4117 containsAllFalse = "Set " + setName + " did not contain the the" +\
4118 " subset " + setPattern
4119
4120 cmdStr = "set-test-get "
4121 cmdStr += setName + " " + values
4122 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004123 try:
Jon Halla495f562016-05-16 18:03:26 -07004124 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004125 # TODO: Maybe make this less hardcoded
4126 # ConsistentMap Exceptions
4127 assert "org.onosproject.store.service" not in output
4128 # Node not leader
4129 assert "java.lang.IllegalStateException" not in output
4130 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004131 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004132 "command: " + str( output ) )
4133 retryTime = 30 # Conservative time, given by Madan
4134 main.log.info( "Waiting " + str( retryTime ) +
4135 "seconds before retrying." )
4136 time.sleep( retryTime ) # Due to change in mastership
4137 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004138 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004139 assert "Command not found:" not in output, output
4140 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004141 main.log.info( self.name + ": " + output )
4142
4143 if length == 0:
4144 match = re.search( pattern, output )
4145 else: # if given values
4146 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004147 patternTrue = pattern + "\r\n" + containsTrue
4148 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004149 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004150 patternTrue = pattern + "\r\n" + containsAllTrue
4151 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004152 matchTrue = re.search( patternTrue, output )
4153 matchFalse = re.search( patternFalse, output )
4154 if matchTrue:
4155 containsCheck = main.TRUE
4156 match = matchTrue
4157 elif matchFalse:
4158 containsCheck = main.FALSE
4159 match = matchFalse
4160 else:
4161 main.log.error( self.name + " setTestGet did not match " +\
4162 "expected output" )
4163 main.log.debug( self.name + " expected: " + pattern )
4164 main.log.debug( self.name + " actual: " + repr( output ) )
4165 match = None
4166 if match:
4167 setMatch = match.group( 1 )
4168 if setMatch == '':
4169 setList = []
4170 else:
4171 setList = setMatch.split( ", " )
4172 if length > 0:
4173 return ( setList, containsCheck )
4174 else:
4175 return setList
4176 else: # no match
4177 main.log.error( self.name + ": setTestGet did not" +
4178 " match expected output" )
4179 main.log.debug( self.name + " expected: " + pattern )
4180 main.log.debug( self.name + " actual: " + repr( output ) )
4181 return main.ERROR
4182 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004183 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004184 return main.ERROR
4185 except TypeError:
4186 main.log.exception( self.name + ": Object not as expected" )
4187 return main.ERROR
4188 except pexpect.EOF:
4189 main.log.error( self.name + ": EOF exception found" )
4190 main.log.error( self.name + ": " + self.handle.before )
4191 main.cleanup()
4192 main.exit()
4193 except Exception:
4194 main.log.exception( self.name + ": Uncaught exception!" )
4195 main.cleanup()
4196 main.exit()
4197
4198 def setTestSize( self, setName ):
4199 """
4200 CLI command to get the elements in a distributed set.
4201 Required arguments:
4202 setName - The name of the set to remove from.
4203 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004204 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004205 None on error
4206 """
4207 try:
4208 # TODO: Should this check against the number of elements returned
4209 # and then return true/false based on that?
4210 setName = str( setName ).strip()
4211 # Patterns to match
4212 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004213 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004214 setPattern
4215 cmdStr = "set-test-get -s "
4216 cmdStr += setName
4217 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004218 try:
Jon Halla495f562016-05-16 18:03:26 -07004219 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004220 # TODO: Maybe make this less hardcoded
4221 # ConsistentMap Exceptions
4222 assert "org.onosproject.store.service" not in output
4223 # Node not leader
4224 assert "java.lang.IllegalStateException" not in output
4225 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004226 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004227 "command: " + str( output ) )
4228 retryTime = 30 # Conservative time, given by Madan
4229 main.log.info( "Waiting " + str( retryTime ) +
4230 "seconds before retrying." )
4231 time.sleep( retryTime ) # Due to change in mastership
4232 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004233 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004234 assert "Command not found:" not in output, output
4235 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004236 main.log.info( self.name + ": " + output )
4237 match = re.search( pattern, output )
4238 if match:
4239 setSize = int( match.group( 1 ) )
4240 setMatch = match.group( 2 )
4241 if len( setMatch.split() ) == setSize:
4242 main.log.info( "The size returned by " + self.name +
4243 " matches the number of elements in " +
4244 "the returned set" )
4245 else:
4246 main.log.error( "The size returned by " + self.name +
4247 " does not match the number of " +
4248 "elements in the returned set." )
4249 return setSize
4250 else: # no match
4251 main.log.error( self.name + ": setTestGet did not" +
4252 " match expected output" )
4253 main.log.debug( self.name + " expected: " + pattern )
4254 main.log.debug( self.name + " actual: " + repr( output ) )
4255 return None
4256 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004257 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004258 return None
Jon Hall390696c2015-05-05 17:13:41 -07004259 except TypeError:
4260 main.log.exception( self.name + ": Object not as expected" )
4261 return None
4262 except pexpect.EOF:
4263 main.log.error( self.name + ": EOF exception found" )
4264 main.log.error( self.name + ": " + self.handle.before )
4265 main.cleanup()
4266 main.exit()
4267 except Exception:
4268 main.log.exception( self.name + ": Uncaught exception!" )
4269 main.cleanup()
4270 main.exit()
4271
Jon Hall80daded2015-05-27 16:07:00 -07004272 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004273 """
4274 Command to list the various counters in the system.
4275 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004276 if jsonFormat, a string of the json object returned by the cli
4277 command
4278 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004279 None on error
4280 """
Jon Hall390696c2015-05-05 17:13:41 -07004281 try:
4282 counters = {}
4283 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004284 if jsonFormat:
4285 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004286 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004287 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004288 assert "Command not found:" not in output, output
4289 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004290 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004291 return output
Jon Hall390696c2015-05-05 17:13:41 -07004292 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004293 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004294 return None
Jon Hall390696c2015-05-05 17:13:41 -07004295 except TypeError:
4296 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004297 return None
Jon Hall390696c2015-05-05 17:13:41 -07004298 except pexpect.EOF:
4299 main.log.error( self.name + ": EOF exception found" )
4300 main.log.error( self.name + ": " + self.handle.before )
4301 main.cleanup()
4302 main.exit()
4303 except Exception:
4304 main.log.exception( self.name + ": Uncaught exception!" )
4305 main.cleanup()
4306 main.exit()
4307
Jon Hall935db192016-04-19 00:22:04 -07004308 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004309 """
Jon Halle1a3b752015-07-22 13:02:46 -07004310 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004311 Required arguments:
4312 counter - The name of the counter to increment.
4313 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004314 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004315 returns:
4316 integer value of the counter or
4317 None on Error
4318 """
4319 try:
4320 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004321 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004322 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004323 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004324 if delta != 1:
4325 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004326 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004327 try:
Jon Halla495f562016-05-16 18:03:26 -07004328 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004329 # TODO: Maybe make this less hardcoded
4330 # ConsistentMap Exceptions
4331 assert "org.onosproject.store.service" not in output
4332 # Node not leader
4333 assert "java.lang.IllegalStateException" not in output
4334 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004335 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004336 "command: " + str( output ) )
4337 retryTime = 30 # Conservative time, given by Madan
4338 main.log.info( "Waiting " + str( retryTime ) +
4339 "seconds before retrying." )
4340 time.sleep( retryTime ) # Due to change in mastership
4341 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004342 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004343 assert "Command not found:" not in output, output
4344 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004345 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004346 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004347 match = re.search( pattern, output )
4348 if match:
4349 return int( match.group( 1 ) )
4350 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004351 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004352 " match expected output." )
4353 main.log.debug( self.name + " expected: " + pattern )
4354 main.log.debug( self.name + " actual: " + repr( output ) )
4355 return None
4356 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004357 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004358 return None
4359 except TypeError:
4360 main.log.exception( self.name + ": Object not as expected" )
4361 return None
4362 except pexpect.EOF:
4363 main.log.error( self.name + ": EOF exception found" )
4364 main.log.error( self.name + ": " + self.handle.before )
4365 main.cleanup()
4366 main.exit()
4367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
4369 main.cleanup()
4370 main.exit()
4371
Jon Hall935db192016-04-19 00:22:04 -07004372 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004373 """
4374 CLI command to get a distributed counter then add a delta to it.
4375 Required arguments:
4376 counter - The name of the counter to increment.
4377 Optional arguments:
4378 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004379 returns:
4380 integer value of the counter or
4381 None on Error
4382 """
4383 try:
4384 counter = str( counter )
4385 delta = int( delta )
4386 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004387 cmdStr += counter
4388 if delta != 1:
4389 cmdStr += " " + str( delta )
4390 output = self.sendline( cmdStr )
4391 try:
Jon Halla495f562016-05-16 18:03:26 -07004392 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004393 # TODO: Maybe make this less hardcoded
4394 # ConsistentMap Exceptions
4395 assert "org.onosproject.store.service" not in output
4396 # Node not leader
4397 assert "java.lang.IllegalStateException" not in output
4398 except AssertionError:
4399 main.log.error( "Error in processing '" + cmdStr + "' " +
4400 "command: " + str( output ) )
4401 retryTime = 30 # Conservative time, given by Madan
4402 main.log.info( "Waiting " + str( retryTime ) +
4403 "seconds before retrying." )
4404 time.sleep( retryTime ) # Due to change in mastership
4405 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004406 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004407 assert "Command not found:" not in output, output
4408 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004409 main.log.info( self.name + ": " + output )
4410 pattern = counter + " was updated to (-?\d+)"
4411 match = re.search( pattern, output )
4412 if match:
4413 return int( match.group( 1 ) )
4414 else:
4415 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4416 " match expected output." )
4417 main.log.debug( self.name + " expected: " + pattern )
4418 main.log.debug( self.name + " actual: " + repr( output ) )
4419 return None
4420 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004421 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004422 return None
4423 except TypeError:
4424 main.log.exception( self.name + ": Object not as expected" )
4425 return None
4426 except pexpect.EOF:
4427 main.log.error( self.name + ": EOF exception found" )
4428 main.log.error( self.name + ": " + self.handle.before )
4429 main.cleanup()
4430 main.exit()
4431 except Exception:
4432 main.log.exception( self.name + ": Uncaught exception!" )
4433 main.cleanup()
4434 main.exit()
4435
YPZhangfebf7302016-05-24 16:45:56 -07004436 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004437 """
4438 Description: Execute summary command in onos
4439 Returns: json object ( summary -j ), returns main.FALSE if there is
4440 no output
4441
4442 """
4443 try:
4444 cmdStr = "summary"
4445 if jsonFormat:
4446 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004447 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004448 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004449 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004450 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004451 if not handle:
4452 main.log.error( self.name + ": There is no output in " +
4453 "summary command" )
4454 return main.FALSE
4455 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004456 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004457 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004458 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004459 except TypeError:
4460 main.log.exception( self.name + ": Object not as expected" )
4461 return None
4462 except pexpect.EOF:
4463 main.log.error( self.name + ": EOF exception found" )
4464 main.log.error( self.name + ": " + self.handle.before )
4465 main.cleanup()
4466 main.exit()
4467 except Exception:
4468 main.log.exception( self.name + ": Uncaught exception!" )
4469 main.cleanup()
4470 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004471
Jon Hall935db192016-04-19 00:22:04 -07004472 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004473 """
4474 CLI command to get the value of a key in a consistent map using
4475 transactions. This a test function and can only get keys from the
4476 test map hard coded into the cli command
4477 Required arguments:
4478 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004479 returns:
4480 The string value of the key or
4481 None on Error
4482 """
4483 try:
4484 keyName = str( keyName )
4485 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004486 cmdStr += keyName
4487 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004488 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004489 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004490 try:
4491 # TODO: Maybe make this less hardcoded
4492 # ConsistentMap Exceptions
4493 assert "org.onosproject.store.service" not in output
4494 # Node not leader
4495 assert "java.lang.IllegalStateException" not in output
4496 except AssertionError:
4497 main.log.error( "Error in processing '" + cmdStr + "' " +
4498 "command: " + str( output ) )
4499 return None
4500 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4501 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004502 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004503 return None
4504 else:
4505 match = re.search( pattern, output )
4506 if match:
4507 return match.groupdict()[ 'value' ]
4508 else:
4509 main.log.error( self.name + ": transactionlMapGet did not" +
4510 " match expected output." )
4511 main.log.debug( self.name + " expected: " + pattern )
4512 main.log.debug( self.name + " actual: " + repr( output ) )
4513 return None
Jon Hallc6793552016-01-19 14:18:37 -08004514 except AssertionError:
4515 main.log.exception( "" )
4516 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004517 except TypeError:
4518 main.log.exception( self.name + ": Object not as expected" )
4519 return None
4520 except pexpect.EOF:
4521 main.log.error( self.name + ": EOF exception found" )
4522 main.log.error( self.name + ": " + self.handle.before )
4523 main.cleanup()
4524 main.exit()
4525 except Exception:
4526 main.log.exception( self.name + ": Uncaught exception!" )
4527 main.cleanup()
4528 main.exit()
4529
Jon Hall935db192016-04-19 00:22:04 -07004530 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004531 """
4532 CLI command to put a value into 'numKeys' number of keys in a
4533 consistent map using transactions. This a test function and can only
4534 put into keys named 'Key#' of the test map hard coded into the cli command
4535 Required arguments:
4536 numKeys - Number of keys to add the value to
4537 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004538 returns:
4539 A dictionary whose keys are the name of the keys put into the map
4540 and the values of the keys are dictionaries whose key-values are
4541 'value': value put into map and optionaly
4542 'oldValue': Previous value in the key or
4543 None on Error
4544
4545 Example output
4546 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4547 'Key2': {'value': 'Testing'} }
4548 """
4549 try:
4550 numKeys = str( numKeys )
4551 value = str( value )
4552 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004553 cmdStr += numKeys + " " + value
4554 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004555 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004556 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004557 try:
4558 # TODO: Maybe make this less hardcoded
4559 # ConsistentMap Exceptions
4560 assert "org.onosproject.store.service" not in output
4561 # Node not leader
4562 assert "java.lang.IllegalStateException" not in output
4563 except AssertionError:
4564 main.log.error( "Error in processing '" + cmdStr + "' " +
4565 "command: " + str( output ) )
4566 return None
4567 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4568 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4569 results = {}
4570 for line in output.splitlines():
4571 new = re.search( newPattern, line )
4572 updated = re.search( updatedPattern, line )
4573 if new:
4574 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4575 elif updated:
4576 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004577 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 else:
4579 main.log.error( self.name + ": transactionlMapGet did not" +
4580 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004581 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4582 newPattern,
4583 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004584 main.log.debug( self.name + " actual: " + repr( output ) )
4585 return results
Jon Hallc6793552016-01-19 14:18:37 -08004586 except AssertionError:
4587 main.log.exception( "" )
4588 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004589 except TypeError:
4590 main.log.exception( self.name + ": Object not as expected" )
4591 return None
4592 except pexpect.EOF:
4593 main.log.error( self.name + ": EOF exception found" )
4594 main.log.error( self.name + ": " + self.handle.before )
4595 main.cleanup()
4596 main.exit()
4597 except Exception:
4598 main.log.exception( self.name + ": Uncaught exception!" )
4599 main.cleanup()
4600 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004601
acsmarsdaea66c2015-09-03 11:44:06 -07004602 def maps( self, jsonFormat=True ):
4603 """
4604 Description: Returns result of onos:maps
4605 Optional:
4606 * jsonFormat: enable json formatting of output
4607 """
4608 try:
4609 cmdStr = "maps"
4610 if jsonFormat:
4611 cmdStr += " -j"
4612 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004613 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004614 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004615 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004616 except AssertionError:
4617 main.log.exception( "" )
4618 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004619 except TypeError:
4620 main.log.exception( self.name + ": Object not as expected" )
4621 return None
4622 except pexpect.EOF:
4623 main.log.error( self.name + ": EOF exception found" )
4624 main.log.error( self.name + ": " + self.handle.before )
4625 main.cleanup()
4626 main.exit()
4627 except Exception:
4628 main.log.exception( self.name + ": Uncaught exception!" )
4629 main.cleanup()
4630 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004631
4632 def getSwController( self, uri, jsonFormat=True ):
4633 """
4634 Descrition: Gets the controller information from the device
4635 """
4636 try:
4637 cmd = "device-controllers "
4638 if jsonFormat:
4639 cmd += "-j "
4640 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004641 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004642 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004643 return response
Jon Hallc6793552016-01-19 14:18:37 -08004644 except AssertionError:
4645 main.log.exception( "" )
4646 return None
GlennRC050596c2015-11-18 17:06:41 -08004647 except TypeError:
4648 main.log.exception( self.name + ": Object not as expected" )
4649 return None
4650 except pexpect.EOF:
4651 main.log.error( self.name + ": EOF exception found" )
4652 main.log.error( self.name + ": " + self.handle.before )
4653 main.cleanup()
4654 main.exit()
4655 except Exception:
4656 main.log.exception( self.name + ": Uncaught exception!" )
4657 main.cleanup()
4658 main.exit()
4659
4660 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4661 """
4662 Descrition: sets the controller(s) for the specified device
4663
4664 Parameters:
4665 Required: uri - String: The uri of the device(switch).
4666 ip - String or List: The ip address of the controller.
4667 This parameter can be formed in a couple of different ways.
4668 VALID:
4669 10.0.0.1 - just the ip address
4670 tcp:10.0.0.1 - the protocol and the ip address
4671 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4672 so that you can add controllers with different
4673 protocols and ports
4674 INVALID:
4675 10.0.0.1:6653 - this is not supported by ONOS
4676
4677 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4678 port - The port number.
4679 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4680
4681 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4682 """
4683 try:
4684 cmd = "device-setcontrollers"
4685
4686 if jsonFormat:
4687 cmd += " -j"
4688 cmd += " " + uri
4689 if isinstance( ip, str ):
4690 ip = [ip]
4691 for item in ip:
4692 if ":" in item:
4693 sitem = item.split( ":" )
4694 if len(sitem) == 3:
4695 cmd += " " + item
4696 elif "." in sitem[1]:
4697 cmd += " {}:{}".format(item, port)
4698 else:
4699 main.log.error( "Malformed entry: " + item )
4700 raise TypeError
4701 else:
4702 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004703 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004704 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004705 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004706 if "Error" in response:
4707 main.log.error( response )
4708 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004710 except AssertionError:
4711 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004712 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004713 except TypeError:
4714 main.log.exception( self.name + ": Object not as expected" )
4715 return main.FALSE
4716 except pexpect.EOF:
4717 main.log.error( self.name + ": EOF exception found" )
4718 main.log.error( self.name + ": " + self.handle.before )
4719 main.cleanup()
4720 main.exit()
4721 except Exception:
4722 main.log.exception( self.name + ": Uncaught exception!" )
4723 main.cleanup()
4724 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004725
4726 def removeDevice( self, device ):
4727 '''
4728 Description:
4729 Remove a device from ONOS by passing the uri of the device(s).
4730 Parameters:
4731 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4732 Returns:
4733 Returns main.FALSE if an exception is thrown or an error is present
4734 in the response. Otherwise, returns main.TRUE.
4735 NOTE:
4736 If a host cannot be removed, then this function will return main.FALSE
4737 '''
4738 try:
4739 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004740 deviceStr = device
4741 device = []
4742 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004743
4744 for d in device:
4745 time.sleep( 1 )
4746 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004747 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004748 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004749 if "Error" in response:
4750 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4751 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004752 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004753 except AssertionError:
4754 main.log.exception( "" )
4755 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004756 except TypeError:
4757 main.log.exception( self.name + ": Object not as expected" )
4758 return main.FALSE
4759 except pexpect.EOF:
4760 main.log.error( self.name + ": EOF exception found" )
4761 main.log.error( self.name + ": " + self.handle.before )
4762 main.cleanup()
4763 main.exit()
4764 except Exception:
4765 main.log.exception( self.name + ": Uncaught exception!" )
4766 main.cleanup()
4767 main.exit()
4768
4769 def removeHost( self, host ):
4770 '''
4771 Description:
4772 Remove a host from ONOS by passing the id of the host(s)
4773 Parameters:
4774 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4775 Returns:
4776 Returns main.FALSE if an exception is thrown or an error is present
4777 in the response. Otherwise, returns main.TRUE.
4778 NOTE:
4779 If a host cannot be removed, then this function will return main.FALSE
4780 '''
4781 try:
4782 if type( host ) is str:
4783 host = list( host )
4784
4785 for h in host:
4786 time.sleep( 1 )
4787 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004788 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004789 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004790 if "Error" in response:
4791 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4792 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004793 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004794 except AssertionError:
4795 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004796 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004797 except TypeError:
4798 main.log.exception( self.name + ": Object not as expected" )
4799 return main.FALSE
4800 except pexpect.EOF:
4801 main.log.error( self.name + ": EOF exception found" )
4802 main.log.error( self.name + ": " + self.handle.before )
4803 main.cleanup()
4804 main.exit()
4805 except Exception:
4806 main.log.exception( self.name + ": Uncaught exception!" )
4807 main.cleanup()
4808 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004809
YPZhangfebf7302016-05-24 16:45:56 -07004810 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004811 '''
4812 Description:
4813 Bring link down or up in the null-provider.
4814 params:
4815 begin - (string) One end of a device or switch.
4816 end - (string) the other end of the device or switch
4817 returns:
4818 main.TRUE if no exceptions were thrown and no Errors are
4819 present in the resoponse. Otherwise, returns main.FALSE
4820 '''
4821 try:
Jon Hallc6793552016-01-19 14:18:37 -08004822 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004823 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004824 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004825 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004826 if "Error" in response or "Failure" in response:
4827 main.log.error( response )
4828 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004829 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004830 except AssertionError:
4831 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004832 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004833 except TypeError:
4834 main.log.exception( self.name + ": Object not as expected" )
4835 return main.FALSE
4836 except pexpect.EOF:
4837 main.log.error( self.name + ": EOF exception found" )
4838 main.log.error( self.name + ": " + self.handle.before )
4839 main.cleanup()
4840 main.exit()
4841 except Exception:
4842 main.log.exception( self.name + ": Uncaught exception!" )
4843 main.cleanup()
4844 main.exit()
4845
Jon Hall2c8959e2016-12-16 12:17:34 -08004846 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004847 '''
4848 Description:
4849 Changes the state of port in an OF switch by means of the
4850 PORTSTATUS OF messages.
4851 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004852 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4853 port - (string) target port in the device. Ex: '2'
4854 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004855 returns:
4856 main.TRUE if no exceptions were thrown and no Errors are
4857 present in the resoponse. Otherwise, returns main.FALSE
4858 '''
4859 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004860 state = state.lower()
4861 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004862 cmd = "portstate {} {} {}".format( dpid, port, state )
4863 response = self.sendline( cmd, showResponse=True )
4864 assert response is not None, "Error in sendline"
4865 assert "Command not found:" not in response, response
4866 if "Error" in response or "Failure" in response:
4867 main.log.error( response )
4868 return main.FALSE
4869 return main.TRUE
4870 except AssertionError:
4871 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004872 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004873 except TypeError:
4874 main.log.exception( self.name + ": Object not as expected" )
4875 return main.FALSE
4876 except pexpect.EOF:
4877 main.log.error( self.name + ": EOF exception found" )
4878 main.log.error( self.name + ": " + self.handle.before )
4879 main.cleanup()
4880 main.exit()
4881 except Exception:
4882 main.log.exception( self.name + ": Uncaught exception!" )
4883 main.cleanup()
4884 main.exit()
4885
4886 def logSet( self, level="INFO", app="org.onosproject" ):
4887 """
4888 Set the logging level to lvl for a specific app
4889 returns main.TRUE on success
4890 returns main.FALSE if Error occurred
4891 if noExit is True, TestON will not exit, but clean up
4892 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4893 Level defaults to INFO
4894 """
4895 try:
4896 self.handle.sendline( "log:set %s %s" %( level, app ) )
4897 self.handle.expect( "onos>" )
4898
4899 response = self.handle.before
4900 if re.search( "Error", response ):
4901 return main.FALSE
4902 return main.TRUE
4903 except pexpect.TIMEOUT:
4904 main.log.exception( self.name + ": TIMEOUT exception found" )
4905 main.cleanup()
4906 main.exit()
4907 except pexpect.EOF:
4908 main.log.error( self.name + ": EOF exception found" )
4909 main.log.error( self.name + ": " + self.handle.before )
4910 main.cleanup()
4911 main.exit()
4912 except Exception:
4913 main.log.exception( self.name + ": Uncaught exception!" )
4914 main.cleanup()
4915 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004916
4917 def getGraphDict( self, timeout=60, includeHost=False ):
4918 """
4919 Return a dictionary which describes the latest network topology data as a
4920 graph.
4921 An example of the dictionary:
4922 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4923 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4924 Each vertex should at least have an 'edges' attribute which describes the
4925 adjacency information. The value of 'edges' attribute is also represented by
4926 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4927 list of attributes.
4928 An example of the edges dictionary:
4929 'edges': { vertex2: { 'port': ..., 'weight': ... },
4930 vertex3: { 'port': ..., 'weight': ... } }
4931 If includeHost == True, all hosts (and host-switch links) will be included
4932 in topology data.
4933 """
4934 graphDict = {}
4935 try:
4936 links = self.links()
4937 links = json.loads( links )
4938 devices = self.devices()
4939 devices = json.loads( devices )
4940 idToDevice = {}
4941 for device in devices:
4942 idToDevice[ device[ 'id' ] ] = device
4943 if includeHost:
4944 hosts = self.hosts()
4945 # FIXME: support 'includeHost' argument
4946 for link in links:
4947 nodeA = link[ 'src' ][ 'device' ]
4948 nodeB = link[ 'dst' ][ 'device' ]
4949 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4950 if not nodeA in graphDict.keys():
4951 graphDict[ nodeA ] = { 'edges':{},
4952 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4953 'type':idToDevice[ nodeA ][ 'type' ],
4954 'available':idToDevice[ nodeA ][ 'available' ],
4955 'role':idToDevice[ nodeA ][ 'role' ],
4956 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4957 'hw':idToDevice[ nodeA ][ 'hw' ],
4958 'sw':idToDevice[ nodeA ][ 'sw' ],
4959 'serial':idToDevice[ nodeA ][ 'serial' ],
4960 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4961 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4962 else:
4963 # Assert nodeB is not connected to any current links of nodeA
4964 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4965 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4966 'type':link[ 'type' ],
4967 'state':link[ 'state' ] }
4968 return graphDict
4969 except ( TypeError, ValueError ):
4970 main.log.exception( self.name + ": Object not as expected" )
4971 return None
4972 except KeyError:
4973 main.log.exception( self.name + ": KeyError exception found" )
4974 return None
4975 except AssertionError:
4976 main.log.exception( self.name + ": AssertionError exception found" )
4977 return None
4978 except pexpect.EOF:
4979 main.log.error( self.name + ": EOF exception found" )
4980 main.log.error( self.name + ": " + self.handle.before )
4981 return None
4982 except Exception:
4983 main.log.exception( self.name + ": Uncaught exception!" )
4984 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004985
4986 def getIntentPerfSummary( self ):
4987 '''
4988 Send command to check intent-perf summary
4989 Returns: dictionary for intent-perf summary
4990 if something wrong, function will return None
4991 '''
4992 cmd = "intent-perf -s"
4993 respDic = {}
4994 resp = self.sendline( cmd )
4995 try:
4996 # Generate the dictionary to return
4997 for l in resp.split( "\n" ):
4998 # Delete any white space in line
4999 temp = re.sub( r'\s+', '', l )
5000 temp = temp.split( ":" )
5001 respDic[ temp[0] ] = temp[ 1 ]
5002
5003 except (TypeError, ValueError):
5004 main.log.exception( self.name + ": Object not as expected" )
5005 return None
5006 except KeyError:
5007 main.log.exception( self.name + ": KeyError exception found" )
5008 return None
5009 except AssertionError:
5010 main.log.exception( self.name + ": AssertionError exception found" )
5011 return None
5012 except pexpect.EOF:
5013 main.log.error( self.name + ": EOF exception found" )
5014 main.log.error( self.name + ": " + self.handle.before )
5015 return None
5016 except Exception:
5017 main.log.exception( self.name + ": Uncaught exception!" )
5018 return None
5019 return respDic
5020
Chiyu Chengec63bde2016-11-17 18:11:36 -08005021 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005022 """
5023 Searches the latest ONOS log file for the given search term and
5024 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005025
chengchiyu08303a02016-09-08 17:40:26 -07005026 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005027 searchTerm:
5028 The string to grep from the ONOS log.
5029 startLine:
5030 The term that decides which line is the start to search the searchTerm in
5031 the karaf log. For now, startTerm only works in 'first' mode.
5032 logNum:
5033 In some extreme cases, one karaf log is not big enough to contain all the
5034 information.Because of this, search mutiply logs is necessary to capture
5035 the right result. logNum is the number of karaf logs that we need to search
5036 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005037 mode:
5038 all: return all the strings that contain the search term
5039 last: return the last string that contains the search term
5040 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005041 num: return the number of times that the searchTerm appears in the log
5042 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005043 """
5044 try:
5045 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005046 #Build the log paths string
5047 logPath = '/opt/onos/log/karaf.log.'
5048 logPaths = '/opt/onos/log/karaf.log'
5049 for i in range( 1, logNum ):
5050 logPaths = logPath + str( i ) + " " + logPaths
5051 cmd = "cat " + logPaths
5052 if mode == 'all':
5053 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005054 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005055 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005056 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005057 if startLine != '':
5058 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5059 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5060 else:
5061 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005062 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005063 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005064 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005065 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005066 if mode == 'total':
5067 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5068 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005069 before = self.sendline( cmd )
5070 before = before.splitlines()
5071 # make sure the returned list only contains the search term
5072 returnLines = [line for line in before if searchTerm in line]
5073 return returnLines
5074 except AssertionError:
5075 main.log.error( self.name + " searchTerm is not string type" )
5076 return None
5077 except pexpect.EOF:
5078 main.log.error( self.name + ": EOF exception found" )
5079 main.log.error( self.name + ": " + self.handle.before )
5080 main.cleanup()
5081 main.exit()
5082 except pexpect.TIMEOUT:
5083 main.log.error( self.name + ": TIMEOUT exception found" )
5084 main.log.error( self.name + ": " + self.handle.before )
5085 main.cleanup()
5086 main.exit()
5087 except Exception:
5088 main.log.exception( self.name + ": Uncaught exception!" )
5089 main.cleanup()
5090 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005091
5092 def vplsShow( self, jsonFormat=True ):
5093 """
5094 Description: Returns result of onos:vpls show, which should list the
5095 configured VPLS networks and the assigned interfaces.
5096 Optional:
5097 * jsonFormat: enable json formatting of output
5098 Returns:
5099 The output of the command or None on error.
5100 """
5101 try:
5102 cmdStr = "vpls show"
5103 if jsonFormat:
5104 raise NotImplementedError
5105 cmdStr += " -j"
5106 handle = self.sendline( cmdStr )
5107 assert handle is not None, "Error in sendline"
5108 assert "Command not found:" not in handle, handle
5109 return handle
5110 except AssertionError:
5111 main.log.exception( "" )
5112 return None
5113 except TypeError:
5114 main.log.exception( self.name + ": Object not as expected" )
5115 return None
5116 except pexpect.EOF:
5117 main.log.error( self.name + ": EOF exception found" )
5118 main.log.error( self.name + ": " + self.handle.before )
5119 main.cleanup()
5120 main.exit()
5121 except NotImplementedError:
5122 main.log.exception( self.name + ": Json output not supported")
5123 return None
5124 except Exception:
5125 main.log.exception( self.name + ": Uncaught exception!" )
5126 main.cleanup()
5127 main.exit()
5128
5129 def parseVplsShow( self ):
5130 """
5131 Parse the cli output of 'vpls show' into json output. This is required
5132 as there is currently no json output available.
5133 """
5134 try:
5135 output = []
5136 raw = self.vplsShow( jsonFormat=False )
5137 namePat = "VPLS name: (?P<name>\w+)"
5138 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5139 encapPat = "Encapsulation: (?P<encap>\w+)"
5140 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5141 mIter = re.finditer( pattern, raw )
5142 for match in mIter:
5143 item = {}
5144 item[ 'name' ] = match.group( 'name' )
5145 ifaces = match.group( 'interfaces' ).split( ', ')
5146 if ifaces == [ "" ]:
5147 ifaces = []
5148 item[ 'interfaces' ] = ifaces
5149 encap = match.group( 'encap' )
5150 if encap != 'NONE':
5151 item[ 'encapsulation' ] = encap.lower()
5152 output.append( item )
5153 return output
5154 except Exception:
5155 main.log.exception( self.name + ": Uncaught exception!" )
5156 main.cleanup()
5157 main.exit()
5158
5159 def vplsList( self, jsonFormat=True ):
5160 """
5161 Description: Returns result of onos:vpls list, which should list the
5162 configured VPLS networks.
5163 Optional:
5164 * jsonFormat: enable json formatting of output
5165 """
5166 try:
5167 cmdStr = "vpls list"
5168 if jsonFormat:
5169 raise NotImplementedError
5170 cmdStr += " -j"
5171 handle = self.sendline( cmdStr )
5172 assert handle is not None, "Error in sendline"
5173 assert "Command not found:" not in handle, handle
5174 return handle
5175 except AssertionError:
5176 main.log.exception( "" )
5177 return None
5178 except TypeError:
5179 main.log.exception( self.name + ": Object not as expected" )
5180 return None
5181 except pexpect.EOF:
5182 main.log.error( self.name + ": EOF exception found" )
5183 main.log.error( self.name + ": " + self.handle.before )
5184 main.cleanup()
5185 main.exit()
5186 except NotImplementedError:
5187 main.log.exception( self.name + ": Json output not supported")
5188 return None
5189 except Exception:
5190 main.log.exception( self.name + ": Uncaught exception!" )
5191 main.cleanup()
5192 main.exit()
5193
5194 def vplsCreate( self, network ):
5195 """
5196 CLI command to create a new VPLS network.
5197 Required arguments:
5198 network - String name of the network to create.
5199 returns:
5200 main.TRUE on success and main.FALSE on failure
5201 """
5202 try:
5203 network = str( network )
5204 cmdStr = "vpls create "
5205 cmdStr += network
5206 output = self.sendline( cmdStr )
5207 assert output is not None, "Error in sendline"
5208 assert "Command not found:" not in output, output
5209 assert "Error executing command" not in output, output
5210 assert "VPLS already exists:" not in output, output
5211 return main.TRUE
5212 except AssertionError:
5213 main.log.exception( "" )
5214 return main.FALSE
5215 except TypeError:
5216 main.log.exception( self.name + ": Object not as expected" )
5217 return main.FALSE
5218 except pexpect.EOF:
5219 main.log.error( self.name + ": EOF exception found" )
5220 main.log.error( self.name + ": " + self.handle.before )
5221 main.cleanup()
5222 main.exit()
5223 except Exception:
5224 main.log.exception( self.name + ": Uncaught exception!" )
5225 main.cleanup()
5226 main.exit()
5227
5228 def vplsDelete( self, network ):
5229 """
5230 CLI command to delete a VPLS network.
5231 Required arguments:
5232 network - Name of the network to delete.
5233 returns:
5234 main.TRUE on success and main.FALSE on failure
5235 """
5236 try:
5237 network = str( network )
5238 cmdStr = "vpls delete "
5239 cmdStr += network
5240 output = self.sendline( cmdStr )
5241 assert output is not None, "Error in sendline"
5242 assert "Command not found:" not in output, output
5243 assert "Error executing command" not in output, output
5244 assert " not found" not in output, output
5245 return main.TRUE
5246 except AssertionError:
5247 main.log.exception( "" )
5248 return main.FALSE
5249 except TypeError:
5250 main.log.exception( self.name + ": Object not as expected" )
5251 return main.FALSE
5252 except pexpect.EOF:
5253 main.log.error( self.name + ": EOF exception found" )
5254 main.log.error( self.name + ": " + self.handle.before )
5255 main.cleanup()
5256 main.exit()
5257 except Exception:
5258 main.log.exception( self.name + ": Uncaught exception!" )
5259 main.cleanup()
5260 main.exit()
5261
5262 def vplsAddIface( self, network, iface ):
5263 """
5264 CLI command to add an interface to a VPLS network.
5265 Required arguments:
5266 network - Name of the network to add the interface to.
5267 iface - The ONOS name for an interface.
5268 returns:
5269 main.TRUE on success and main.FALSE on failure
5270 """
5271 try:
5272 network = str( network )
5273 iface = str( iface )
5274 cmdStr = "vpls add-if "
5275 cmdStr += network + " " + iface
5276 output = self.sendline( cmdStr )
5277 assert output is not None, "Error in sendline"
5278 assert "Command not found:" not in output, output
5279 assert "Error executing command" not in output, output
5280 assert "already associated to network" not in output, output
5281 assert "Interface cannot be added." not in output, output
5282 return main.TRUE
5283 except AssertionError:
5284 main.log.exception( "" )
5285 return main.FALSE
5286 except TypeError:
5287 main.log.exception( self.name + ": Object not as expected" )
5288 return main.FALSE
5289 except pexpect.EOF:
5290 main.log.error( self.name + ": EOF exception found" )
5291 main.log.error( self.name + ": " + self.handle.before )
5292 main.cleanup()
5293 main.exit()
5294 except Exception:
5295 main.log.exception( self.name + ": Uncaught exception!" )
5296 main.cleanup()
5297 main.exit()
5298
5299 def vplsRemIface( self, network, iface ):
5300 """
5301 CLI command to remove an interface from a VPLS network.
5302 Required arguments:
5303 network - Name of the network to remove the interface from.
5304 iface - Name of the interface to remove.
5305 returns:
5306 main.TRUE on success and main.FALSE on failure
5307 """
5308 try:
5309 iface = str( iface )
5310 cmdStr = "vpls rem-if "
5311 cmdStr += network + " " + iface
5312 output = self.sendline( cmdStr )
5313 assert output is not None, "Error in sendline"
5314 assert "Command not found:" not in output, output
5315 assert "Error executing command" not in output, output
5316 assert "is not configured" not in output, output
5317 return main.TRUE
5318 except AssertionError:
5319 main.log.exception( "" )
5320 return main.FALSE
5321 except TypeError:
5322 main.log.exception( self.name + ": Object not as expected" )
5323 return main.FALSE
5324 except pexpect.EOF:
5325 main.log.error( self.name + ": EOF exception found" )
5326 main.log.error( self.name + ": " + self.handle.before )
5327 main.cleanup()
5328 main.exit()
5329 except Exception:
5330 main.log.exception( self.name + ": Uncaught exception!" )
5331 main.cleanup()
5332 main.exit()
5333
5334 def vplsClean( self ):
5335 """
5336 Description: Clears the VPLS app configuration.
5337 Returns: main.TRUE on success and main.FALSE on failure
5338 """
5339 try:
5340 cmdStr = "vpls clean"
5341 handle = self.sendline( cmdStr )
5342 assert handle is not None, "Error in sendline"
5343 assert "Command not found:" not in handle, handle
5344 return handle
5345 except AssertionError:
5346 main.log.exception( "" )
5347 return main.FALSE
5348 except TypeError:
5349 main.log.exception( self.name + ": Object not as expected" )
5350 return main.FALSE
5351 except pexpect.EOF:
5352 main.log.error( self.name + ": EOF exception found" )
5353 main.log.error( self.name + ": " + self.handle.before )
5354 main.cleanup()
5355 main.exit()
5356 except Exception:
5357 main.log.exception( self.name + ": Uncaught exception!" )
5358 main.cleanup()
5359 main.exit()
5360
5361 def vplsSetEncap( self, network, encapType ):
5362 """
5363 CLI command to add an interface to a VPLS network.
5364 Required arguments:
5365 network - Name of the network to create.
5366 encapType - Type of encapsulation.
5367 returns:
5368 main.TRUE on success and main.FALSE on failure
5369 """
5370 try:
5371 network = str( network )
5372 encapType = str( encapType ).upper()
5373 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5374 cmdStr = "vpls set-encap "
5375 cmdStr += network + " " + encapType
5376 output = self.sendline( cmdStr )
5377 assert output is not None, "Error in sendline"
5378 assert "Command not found:" not in output, output
5379 assert "Error executing command" not in output, output
5380 assert "already associated to network" not in output, output
5381 assert "Encapsulation type " not in output, output
5382 return main.TRUE
5383 except AssertionError:
5384 main.log.exception( "" )
5385 return main.FALSE
5386 except TypeError:
5387 main.log.exception( self.name + ": Object not as expected" )
5388 return main.FALSE
5389 except pexpect.EOF:
5390 main.log.error( self.name + ": EOF exception found" )
5391 main.log.error( self.name + ": " + self.handle.before )
5392 main.cleanup()
5393 main.exit()
5394 except Exception:
5395 main.log.exception( self.name + ": Uncaught exception!" )
5396 main.cleanup()
5397 main.exit()
5398
5399 def interfaces( self, jsonFormat=True ):
5400 """
5401 Description: Returns result of interfaces command.
5402 Optional:
5403 * jsonFormat: enable json formatting of output
5404 Returns:
5405 The output of the command or None on error.
5406 """
5407 try:
5408 cmdStr = "interfaces"
5409 if jsonFormat:
5410 #raise NotImplementedError
5411 cmdStr += " -j"
5412 handle = self.sendline( cmdStr )
5413 assert handle is not None, "Error in sendline"
5414 assert "Command not found:" not in handle, handle
5415 return handle
5416 except AssertionError:
5417 main.log.exception( "" )
5418 return None
5419 except TypeError:
5420 main.log.exception( self.name + ": Object not as expected" )
5421 return None
5422 except pexpect.EOF:
5423 main.log.error( self.name + ": EOF exception found" )
5424 main.log.error( self.name + ": " + self.handle.before )
5425 main.cleanup()
5426 main.exit()
5427 except NotImplementedError:
5428 main.log.exception( self.name + ": Json output not supported")
5429 return None
5430 except Exception:
5431 main.log.exception( self.name + ": Uncaught exception!" )
5432 main.cleanup()
5433 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005434
5435 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5436 '''
5437 Get the timestamp of searchTerm from karaf log.
5438
5439 Arguments:
5440 splitTerm_before and splitTerm_after:
5441
5442 The terms that split the string that contains the timeStamp of
5443 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5444 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5445 and the splitTerm_after is "x"
5446
5447 others:
5448
5449 plz look at the "logsearch" Function in onosclidriver.py
5450
5451
5452 '''
5453 if logNum < 0:
5454 main.log.error("Get wrong log number ")
5455 return main.ERROR
5456 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5457 if len(lines) == 0:
5458 main.log.warn( "Captured timestamp string is empty" )
5459 return main.ERROR
5460 lines = lines[ 0 ]
5461 try:
5462 assert type(lines) is str
5463 # get the target value
5464 line = lines.split( splitTerm_before )
5465 key = line[ 1 ].split( splitTerm_after )
5466 return int( key[ 0 ] )
5467 except IndexError:
5468 main.log.warn( "Index Error!" )
5469 return main.ERROR
5470 except AssertionError:
5471 main.log.warn( "Search Term Not Found " )
5472 return main.ERROR