blob: 4d8cec7cff61d56f4e36caa7cac16e17fbc88699 [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
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
154 self.handle.expect( "\$" )
155 return main.TRUE
156 else: # some other output
157 main.log.warn( "Unknown repsonse to logout command: '{}'",
158 repr( self.handle.before ) )
159 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700160 elif i == 1: # not in CLI
161 return main.TRUE
162 elif i == 3: # Timeout
163 return main.FALSE
164 else:
andrewonlab9627f432014-11-14 12:45:10 -0500165 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800166 except TypeError:
167 main.log.exception( self.name + ": Object not as expected" )
168 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700171 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 main.cleanup()
173 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700174 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700175 main.log.error( self.name +
176 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800177 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800178 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 main.cleanup()
180 main.exit()
181
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800183 """
andrewonlab95ce8322014-10-13 14:12:04 -0400184 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800185
andrewonlab95ce8322014-10-13 14:12:04 -0400186 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800187 """
andrewonlab95ce8322014-10-13 14:12:04 -0400188 try:
189 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400191 main.cleanup()
192 main.exit()
193 else:
kelvin8ec71442015-01-15 16:57:00 -0800194 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800196 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400197 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800198 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800199 handleBefore = self.handle.before
200 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800201 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800202 self.handle.sendline("")
203 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800204 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400205
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 main.log.info( "Cell call returned: " + handleBefore +
207 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400208
209 return main.TRUE
210
Jon Halld4d4b372015-01-28 16:02:41 -0800211 except TypeError:
212 main.log.exception( self.name + ": Object not as expected" )
213 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400214 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800215 main.log.error( self.name + ": eof exception found" )
216 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400217 main.cleanup()
218 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800220 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400221 main.cleanup()
222 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800223
pingping-lin57a56ce2015-05-20 16:43:48 -0700224 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800225 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800226 """
Jon Hallefbd9792015-03-05 16:11:36 -0800227 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 by user would be used to set the current karaf shell idle timeout.
229 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800230 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 Below is an example to start a session with 60 seconds idle timeout
232 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800233
Hari Krishna25d42f72015-01-05 15:08:28 -0800234 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 Note: karafTimeout is left as str so that this could be read
238 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800239 """
You Wangf69ab392016-01-26 16:34:38 -0800240 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400241 try:
kelvin8ec71442015-01-15 16:57:00 -0800242 self.handle.sendline( "" )
243 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700244 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500245
246 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800247 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500248 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400249
kelvin8ec71442015-01-15 16:57:00 -0800250 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 i = self.handle.expect( [
253 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400255
256 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800258 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800259 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800260 "config:property-set -p org.apache.karaf.shell\
261 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800262 karafTimeout )
263 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400266 return main.TRUE
267 else:
kelvin8ec71442015-01-15 16:57:00 -0800268 # If failed, send ctrl+c to process and try again
269 main.log.info( "Starting CLI failed. Retrying..." )
270 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800272 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
273 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400274 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800276 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800277 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800278 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 "config:property-set -p org.apache.karaf.shell\
280 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800281 karafTimeout )
282 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800284 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400285 return main.TRUE
286 else:
kelvin8ec71442015-01-15 16:57:00 -0800287 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400290
Jon Halld4d4b372015-01-28 16:02:41 -0800291 except TypeError:
292 main.log.exception( self.name + ": Object not as expected" )
293 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800295 main.log.error( self.name + ": EOF exception found" )
296 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400297 main.cleanup()
298 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800300 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400301 main.cleanup()
302 main.exit()
303
suibin zhang116647a2016-05-06 16:30:09 -0700304 def startCellCli( self, karafTimeout="",
305 commandlineTimeout=10, onosStartTimeout=60 ):
306 """
307 Start CLI on onos ecll handle.
308
309 karafTimeout is an optional argument. karafTimeout value passed
310 by user would be used to set the current karaf shell idle timeout.
311 Note that when ever this property is modified the shell will exit and
312 the subsequent login would reflect new idle timeout.
313 Below is an example to start a session with 60 seconds idle timeout
314 ( input value is in milliseconds ):
315
316 tValue = "60000"
317
318 Note: karafTimeout is left as str so that this could be read
319 and passed to startOnosCli from PARAMS file as str.
320 """
321
322 try:
323 self.handle.sendline( "" )
324 x = self.handle.expect( [
325 "\$", "onos>" ], commandlineTimeout)
326
327 if x == 1:
328 main.log.info( "ONOS cli is already running" )
329 return main.TRUE
330
331 # Wait for onos start ( -w ) and enter onos cli
332 self.handle.sendline( "/opt/onos/bin/onos" )
333 i = self.handle.expect( [
334 "onos>",
335 pexpect.TIMEOUT ], onosStartTimeout )
336
337 if i == 0:
338 main.log.info( self.name + " CLI Started successfully" )
339 if karafTimeout:
340 self.handle.sendline(
341 "config:property-set -p org.apache.karaf.shell\
342 sshIdleTimeout " +
343 karafTimeout )
344 self.handle.expect( "\$" )
345 self.handle.sendline( "/opt/onos/bin/onos" )
346 self.handle.expect( "onos>" )
347 return main.TRUE
348 else:
349 # If failed, send ctrl+c to process and try again
350 main.log.info( "Starting CLI failed. Retrying..." )
351 self.handle.send( "\x03" )
352 self.handle.sendline( "/opt/onos/bin/onos" )
353 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
354 timeout=30 )
355 if i == 0:
356 main.log.info( self.name + " CLI Started " +
357 "successfully after retry attempt" )
358 if karafTimeout:
359 self.handle.sendline(
360 "config:property-set -p org.apache.karaf.shell\
361 sshIdleTimeout " +
362 karafTimeout )
363 self.handle.expect( "\$" )
364 self.handle.sendline( "/opt/onos/bin/onos" )
365 self.handle.expect( "onos>" )
366 return main.TRUE
367 else:
368 main.log.error( "Connection to CLI " +
369 self.name + " timeout" )
370 return main.FALSE
371
372 except TypeError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
375 except pexpect.EOF:
376 main.log.error( self.name + ": EOF exception found" )
377 main.log.error( self.name + ": " + self.handle.before )
378 main.cleanup()
379 main.exit()
380 except Exception:
381 main.log.exception( self.name + ": Uncaught exception!" )
382 main.cleanup()
383 main.exit()
384
YPZhangebf9eb52016-05-12 15:20:24 -0700385 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800386 """
387 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800388 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800389 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700390 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 Available level: DEBUG, TRACE, INFO, WARN, ERROR
392 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800393 """
394 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800395 lvlStr = ""
396 if level:
397 lvlStr = "--level=" + level
398
kelvin-onlab9f541032015-02-04 16:19:53 -0800399 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800400 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700401 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800402 main.log.error( self.name + ": onos cli session closed. ")
403 if self.onosIp:
404 main.log.warn( "Trying to reconnect " + self.onosIp )
405 reconnectResult = self.startOnosCli( self.onosIp )
406 if reconnectResult:
407 main.log.info( self.name + ": onos cli session reconnected." )
408 else:
409 main.log.error( self.name + ": reconnection failed." )
410 main.cleanup()
411 main.exit()
412 else:
413 main.cleanup()
414 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700415 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700416 self.handle.sendline( "" )
417 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800418 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700419 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800420 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800421
kelvin-onlab9f541032015-02-04 16:19:53 -0800422 response = self.handle.before
423 if re.search( "Error", response ):
424 return main.FALSE
425 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700426 except pexpect.TIMEOUT:
427 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700428 if noExit:
429 main.cleanup()
430 return None
431 else:
432 main.cleanup()
433 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 except pexpect.EOF:
435 main.log.error( self.name + ": EOF exception found" )
436 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700437 if noExit:
438 main.cleanup()
439 return None
440 else:
441 main.cleanup()
442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800443 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800444 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700445 if noExit:
446 main.cleanup()
447 return None
448 else:
449 main.cleanup()
450 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400451
YPZhangebf9eb52016-05-12 15:20:24 -0700452 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800453 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800454 Send a completely user specified string to
455 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400456 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800457
YPZhangebf9eb52016-05-12 15:20:24 -0700458 if noExit is True, TestON will not exit, but clean up
459
andrewonlaba18f6bf2014-10-13 19:31:54 -0400460 Warning: There are no sanity checking to commands
461 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800462
kelvin8ec71442015-01-15 16:57:00 -0800463 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400464 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700465 if debug:
466 # NOTE: This adds and average of .4 seconds per call
467 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700468 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800470 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800471 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800472 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800473 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
474 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700475 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700476 main.log.debug( self.name + ": Raw output" )
477 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700478
479 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800481 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700482 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700483 main.log.debug( self.name + ": ansiEscape output" )
484 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700485
kelvin-onlabfb521662015-02-27 09:52:40 -0800486 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800487 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.log.debug( self.name + ": Removed extra returns " +
490 "from output" )
491 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700492
493 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800494 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700495 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700496 main.log.debug( self.name + ": parsed and stripped output" )
497 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498
Jon Hall63604932015-02-26 17:09:50 -0800499 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 output = response.split( cmdStr.strip(), 1 )
501 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700502 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700504 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800505 output = output[1].strip()
506 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800507 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800508 return output
GlennRCed771242016-01-13 17:02:47 -0800509 except pexpect.TIMEOUT:
510 main.log.error( self.name + ":ONOS timeout" )
511 if debug:
512 main.log.debug( self.handle.before )
513 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 except IndexError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800517 except TypeError:
518 main.log.exception( self.name + ": Object not as expected" )
519 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400520 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800521 main.log.error( self.name + ": EOF exception found" )
522 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700523 if noExit:
524 main.cleanup()
525 return None
526 else:
527 main.cleanup()
528 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800529 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800530 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700531 if noExit:
532 main.cleanup()
533 return None
534 else:
535 main.cleanup()
536 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400537
kelvin8ec71442015-01-15 16:57:00 -0800538 # IMPORTANT NOTE:
539 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800540 # the cli command changing 'a:b' with 'aB'.
541 # Ex ) onos:topology > onosTopology
542 # onos:links > onosLinks
543 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800544
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800546 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400547 Adds a new cluster node by ID and address information.
548 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800549 * nodeId
550 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400551 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800553 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400554 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 cmdStr = "add-node " + str( nodeId ) + " " +\
556 str( ONOSIp ) + " " + str( tcpPort )
557 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800558 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800559 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( "Error in adding node" )
561 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800562 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400563 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800566 except AssertionError:
567 main.log.exception( "" )
568 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800569 except TypeError:
570 main.log.exception( self.name + ": Object not as expected" )
571 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800573 main.log.error( self.name + ": EOF exception found" )
574 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400575 main.cleanup()
576 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800577 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800578 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 main.cleanup()
580 main.exit()
581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlab86dc3082014-10-13 18:18:38 -0400584 Removes a cluster by ID
585 Issues command: 'remove-node [<node-id>]'
586 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800588 """
andrewonlab86dc3082014-10-13 18:18:38 -0400589 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400590
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700592 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800593 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700594 if re.search( "Error", handle ):
595 main.log.error( "Error in removing node" )
596 main.log.error( handle )
597 return main.FALSE
598 else:
599 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800600 except AssertionError:
601 main.log.exception( "" )
602 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800603 except TypeError:
604 main.log.exception( self.name + ": Object not as expected" )
605 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800607 main.log.error( self.name + ": EOF exception found" )
608 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400609 main.cleanup()
610 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800611 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800612 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400613 main.cleanup()
614 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400615
Jon Hall61282e32015-03-19 11:34:11 -0700616 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800617 """
andrewonlab7c211572014-10-15 16:45:20 -0400618 List the nodes currently visible
619 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700620 Optional argument:
621 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800622 """
andrewonlab7c211572014-10-15 16:45:20 -0400623 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700624 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700625 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700626 cmdStr += " -j"
627 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800628 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 return output
Jon Hallc6793552016-01-19 14:18:37 -0800630 except AssertionError:
631 main.log.exception( "" )
632 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800633 except TypeError:
634 main.log.exception( self.name + ": Object not as expected" )
635 return None
andrewonlab7c211572014-10-15 16:45:20 -0400636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400639 main.cleanup()
640 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800641 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800642 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400643 main.cleanup()
644 main.exit()
645
kelvin8ec71442015-01-15 16:57:00 -0800646 def topology( self ):
647 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700648 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700649 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700650 Return:
651 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab95ce8322014-10-13 14:12:04 -0400653 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700654 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800656 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700657 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400658 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800659 except AssertionError:
660 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800661 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800662 except TypeError:
663 main.log.exception( self.name + ": Object not as expected" )
664 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400665 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800666 main.log.error( self.name + ": EOF exception found" )
667 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400668 main.cleanup()
669 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800670 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800671 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400672 main.cleanup()
673 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800674
jenkins7ead5a82015-03-13 10:28:21 -0700675 def deviceRemove( self, deviceId ):
676 """
677 Removes particular device from storage
678
679 TODO: refactor this function
680 """
681 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700682 cmdStr = "device-remove " + str( deviceId )
683 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800684 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700685 if re.search( "Error", handle ):
686 main.log.error( "Error in removing device" )
687 main.log.error( handle )
688 return main.FALSE
689 else:
690 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800691 except AssertionError:
692 main.log.exception( "" )
693 return None
jenkins7ead5a82015-03-13 10:28:21 -0700694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
697 except pexpect.EOF:
698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
700 main.cleanup()
701 main.exit()
702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
704 main.cleanup()
705 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Hall7b02d952014-10-17 20:14:54 -0400709 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400710 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800712 """
andrewonlab86dc3082014-10-13 18:18:38 -0400713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700716 cmdStr += " -j"
717 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800720 except AssertionError:
721 main.log.exception( "" )
722 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800723 except TypeError:
724 main.log.exception( self.name + ": Object not as expected" )
725 return None
andrewonlab7c211572014-10-15 16:45:20 -0400726 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400729 main.cleanup()
730 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800731 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800732 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400733 main.cleanup()
734 main.exit()
735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800737 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800738 This balances the devices across all controllers
739 by issuing command: 'onos> onos:balance-masters'
740 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800742 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700744 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800745 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 if re.search( "Error", handle ):
747 main.log.error( "Error in balancing masters" )
748 main.log.error( handle )
749 return main.FALSE
750 else:
751 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800761 main.cleanup()
762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800765 main.cleanup()
766 main.exit()
767
Jon Hallc6793552016-01-19 14:18:37 -0800768 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700769 """
770 Returns the output of the masters command.
771 Optional argument:
772 * jsonFormat - boolean indicating if you want output in json
773 """
774 try:
775 cmdStr = "onos:masters"
776 if jsonFormat:
777 cmdStr += " -j"
778 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800779 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700780 return output
Jon Hallc6793552016-01-19 14:18:37 -0800781 except AssertionError:
782 main.log.exception( "" )
783 return None
acsmars24950022015-07-30 18:00:43 -0700784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
787 except pexpect.EOF:
788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
790 main.cleanup()
791 main.exit()
792 except Exception:
793 main.log.exception( self.name + ": Uncaught exception!" )
794 main.cleanup()
795 main.exit()
796
Jon Hallc6793552016-01-19 14:18:37 -0800797 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Uses the master command to check that the devices' leadership
800 is evenly divided
801
802 Dependencies: checkMasters() and summary()
803
804 Returns main.True if the devices are balanced
805 Returns main.False if the devices are unbalanced
806 Exits on Exception
807 Returns None on TypeError
808 """
809 try:
Jon Hallc6793552016-01-19 14:18:37 -0800810 summaryOutput = self.summary()
811 totalDevices = json.loads( summaryOutput )[ "devices" ]
812 except ( TypeError, ValueError ):
813 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
814 return None
815 try:
acsmars24950022015-07-30 18:00:43 -0700816 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800817 mastersOutput = self.checkMasters()
818 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700819 first = masters[ 0 ][ "size" ]
820 for master in masters:
821 totalOwnedDevices += master[ "size" ]
822 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
823 main.log.error( "Mastership not balanced" )
824 main.log.info( "\n" + self.checkMasters( False ) )
825 return main.FALSE
826 main.log.info( "Mastership balanced between " \
827 + str( len(masters) ) + " masters" )
828 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800829 except ( TypeError, ValueError ):
830 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700831 return None
832 except pexpect.EOF:
833 main.log.error( self.name + ": EOF exception found" )
834 main.log.error( self.name + ": " + self.handle.before )
835 main.cleanup()
836 main.exit()
837 except Exception:
838 main.log.exception( self.name + ": Uncaught exception!" )
839 main.cleanup()
840 main.exit()
841
kelvin-onlabd3b64892015-01-20 13:26:24 -0800842 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800843 """
Jon Halle8217482014-10-17 13:49:14 -0400844 Lists all core links
845 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Halle8217482014-10-17 13:49:14 -0400848 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700849 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700851 cmdStr += " -j"
852 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800853 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700854 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800855 except AssertionError:
856 main.log.exception( "" )
857 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800858 except TypeError:
859 main.log.exception( self.name + ": Object not as expected" )
860 return None
Jon Halle8217482014-10-17 13:49:14 -0400861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400864 main.cleanup()
865 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800867 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400868 main.cleanup()
869 main.exit()
870
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800872 """
Jon Halle8217482014-10-17 13:49:14 -0400873 Lists all ports
874 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800876 """
Jon Halle8217482014-10-17 13:49:14 -0400877 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700880 cmdStr += " -j"
881 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800882 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700883 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800884 except AssertionError:
885 main.log.exception( "" )
886 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800887 except TypeError:
888 main.log.exception( self.name + ": Object not as expected" )
889 return None
Jon Halle8217482014-10-17 13:49:14 -0400890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800891 main.log.error( self.name + ": EOF exception found" )
892 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400893 main.cleanup()
894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400897 main.cleanup()
898 main.exit()
899
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Hall983a1702014-10-28 18:44:22 -0400902 Lists all devices and the controllers with roles assigned to them
903 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800905 """
andrewonlab7c211572014-10-15 16:45:20 -0400906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700907 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr += " -j"
910 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800911 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700912 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800913 except AssertionError:
914 main.log.exception( "" )
915 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800916 except TypeError:
917 main.log.exception( self.name + ": Object not as expected" )
918 return None
Jon Hall983a1702014-10-28 18:44:22 -0400919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( self.name + ": EOF exception found" )
921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400922 main.cleanup()
923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400926 main.cleanup()
927 main.exit()
928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800930 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800931 Given the a string containing the json representation of the "roles"
932 cli command and a partial or whole device id, returns a json object
933 containing the roles output for the first device whose id contains
934 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400935
936 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800937 A dict of the role assignments for the given device or
938 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Hall983a1702014-10-28 18:44:22 -0400940 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400942 return None
943 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 rawRoles = self.roles()
945 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800946 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800948 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400950 return device
951 return None
Jon Hallc6793552016-01-19 14:18:37 -0800952 except ( TypeError, ValueError ):
953 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800954 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400958 main.cleanup()
959 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800961 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400962 main.cleanup()
963 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800966 """
Jon Hall94fd0472014-12-08 11:52:42 -0800967 Iterates through each device and checks if there is a master assigned
968 Returns: main.TRUE if each device has a master
969 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800970 """
Jon Hall94fd0472014-12-08 11:52:42 -0800971 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 rawRoles = self.roles()
973 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800974 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800976 # print device
977 if device[ 'master' ] == "none":
978 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800979 return main.FALSE
980 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800981 except ( TypeError, ValueError ):
982 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800983 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800984 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800985 main.log.error( self.name + ": EOF exception found" )
986 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800987 main.cleanup()
988 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800989 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800990 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800991 main.cleanup()
992 main.exit()
993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800995 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400996 Returns string of paths, and the cost.
997 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400999 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1001 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001002 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001003 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.error( "Error in getting paths" )
1005 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001006 else:
kelvin8ec71442015-01-15 16:57:00 -08001007 path = handle.split( ";" )[ 0 ]
1008 cost = handle.split( ";" )[ 1 ]
1009 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001010 except AssertionError:
1011 main.log.exception( "" )
1012 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001013 except TypeError:
1014 main.log.exception( self.name + ": Object not as expected" )
1015 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001017 main.log.error( self.name + ": EOF exception found" )
1018 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 main.cleanup()
1020 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001021 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001022 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001023 main.cleanup()
1024 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001025
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001027 """
Jon Hallffb386d2014-11-21 13:43:38 -08001028 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001029 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001030 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001031 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001033 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001035 cmdStr += " -j"
1036 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001037 if handle:
1038 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001039 # TODO: Maybe make this less hardcoded
1040 # ConsistentMap Exceptions
1041 assert "org.onosproject.store.service" not in handle
1042 # Node not leader
1043 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001044 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001045 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001046 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001047 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001048 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001049 except TypeError:
1050 main.log.exception( self.name + ": Object not as expected" )
1051 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001052 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001053 main.log.error( self.name + ": EOF exception found" )
1054 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 main.cleanup()
1056 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001057 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001058 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001059 main.cleanup()
1060 main.exit()
1061
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001063 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001064 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001065
Jon Hallefbd9792015-03-05 16:11:36 -08001066 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001067 partial mac address
1068
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001070 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 try:
kelvin8ec71442015-01-15 16:57:00 -08001072 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001073 return None
1074 else:
1075 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 rawHosts = self.hosts()
1077 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001078 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001080 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001081 if not host:
1082 pass
1083 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001084 return host
1085 return None
Jon Hallc6793552016-01-19 14:18:37 -08001086 except ( TypeError, ValueError ):
1087 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001088 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001090 main.log.error( self.name + ": EOF exception found" )
1091 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 main.cleanup()
1093 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001094 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001095 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 main.cleanup()
1097 main.exit()
1098
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001100 """
1101 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001102 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001103
andrewonlab3f0a4af2014-10-17 12:25:14 -04001104 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001106 IMPORTANT:
1107 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001108 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001109 Furthermore, it assumes that value of VLAN is '-1'
1110 Description:
kelvin8ec71442015-01-15 16:57:00 -08001111 Converts mininet hosts ( h1, h2, h3... ) into
1112 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1113 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001118 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 hostHex = hex( int( host ) ).zfill( 12 )
1120 hostHex = str( hostHex ).replace( 'x', '0' )
1121 i = iter( str( hostHex ) )
1122 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1123 hostHex = hostHex + "/-1"
1124 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001125
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127
Jon Halld4d4b372015-01-28 16:02:41 -08001128 except TypeError:
1129 main.log.exception( self.name + ": Object not as expected" )
1130 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.error( self.name + ": EOF exception found" )
1133 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134 main.cleanup()
1135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001137 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 main.cleanup()
1139 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001140
Jeremy Songsterff553672016-05-12 17:06:23 -07001141 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001142 """
andrewonlabe6745342014-10-17 14:29:13 -04001143 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * hostIdOne: ONOS host id for host1
1145 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001146 Optional:
1147 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001148 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001149 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001150 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001151 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001152 Returns:
1153 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001154 """
andrewonlabe6745342014-10-17 14:29:13 -04001155 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001156 cmdStr = "add-host-intent "
1157 if vlanId:
1158 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001159 if setVlan:
1160 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001161 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001163 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001164 if re.search( "Error", handle ):
1165 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001166 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001167 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001168 else:
1169 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1171 match = re.search('id=0x([\da-f]+),', handle)
1172 if match:
1173 return match.group()[3:-1]
1174 else:
1175 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001176 main.log.debug( "Response from ONOS was: " +
1177 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001178 return None
Jon Hallc6793552016-01-19 14:18:37 -08001179 except AssertionError:
1180 main.log.exception( "" )
1181 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001182 except TypeError:
1183 main.log.exception( self.name + ": Object not as expected" )
1184 return None
andrewonlabe6745342014-10-17 14:29:13 -04001185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001186 main.log.error( self.name + ": EOF exception found" )
1187 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001188 main.cleanup()
1189 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001191 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001192 main.cleanup()
1193 main.exit()
1194
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001196 """
andrewonlab7b31d232014-10-24 13:31:47 -04001197 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * ingressDevice: device id of ingress device
1199 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001200 Optional:
1201 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001202 Description:
1203 Adds an optical intent by specifying an ingress and egress device
1204 Returns:
1205 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001206 """
andrewonlab7b31d232014-10-24 13:31:47 -04001207 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1209 " " + str( egressDevice )
1210 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001211 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001212 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001213 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 main.log.error( "Error in adding Optical intent" )
1215 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001216 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 main.log.info( "Optical intent installed between " +
1218 str( ingressDevice ) + " and " +
1219 str( egressDevice ) )
1220 match = re.search('id=0x([\da-f]+),', handle)
1221 if match:
1222 return match.group()[3:-1]
1223 else:
1224 main.log.error( "Error, intent ID not found" )
1225 return None
Jon Hallc6793552016-01-19 14:18:37 -08001226 except AssertionError:
1227 main.log.exception( "" )
1228 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001229 except TypeError:
1230 main.log.exception( self.name + ": Object not as expected" )
1231 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001235 main.cleanup()
1236 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001238 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001239 main.cleanup()
1240 main.exit()
1241
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001243 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 ingressDevice,
1245 egressDevice,
1246 portIngress="",
1247 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001248 ethType="",
1249 ethSrc="",
1250 ethDst="",
1251 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 ipProto="",
1254 ipSrc="",
1255 ipDst="",
1256 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001257 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001258 vlanId="",
1259 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001260 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001261 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 * ingressDevice: device id of ingress device
1263 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001264 Optional:
1265 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001266 * ethSrc: specify ethSrc ( i.e. src mac addr )
1267 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001268 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001270 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001271 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001272 * ipSrc: specify ip source address
1273 * ipDst: specify ip destination address
1274 * tcpSrc: specify tcp source port
1275 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001276 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001277 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Description:
kelvin8ec71442015-01-15 16:57:00 -08001279 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001280 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001281 Returns:
1282 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001283
Jon Halle3f39ff2015-01-13 11:50:53 -08001284 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001285 options developers provide for point-to-point
1286 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001287 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001288 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001289 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001290
Jeremy Songsterff553672016-05-12 17:06:23 -07001291 if ethType:
1292 cmd += " --ethType " + str( ethType )
1293 if ethSrc:
1294 cmd += " --ethSrc " + str( ethSrc )
1295 if ethDst:
1296 cmd += " --ethDst " + str( ethDst )
1297 if bandwidth:
1298 cmd += " --bandwidth " + str( bandwidth )
1299 if lambdaAlloc:
1300 cmd += " --lambda "
1301 if ipProto:
1302 cmd += " --ipProto " + str( ipProto )
1303 if ipSrc:
1304 cmd += " --ipSrc " + str( ipSrc )
1305 if ipDst:
1306 cmd += " --ipDst " + str( ipDst )
1307 if tcpSrc:
1308 cmd += " --tcpSrc " + str( tcpSrc )
1309 if tcpDst:
1310 cmd += " --tcpDst " + str( tcpDst )
1311 if vlanId:
1312 cmd += " -v " + str( vlanId )
1313 if setVlan:
1314 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001315
kelvin8ec71442015-01-15 16:57:00 -08001316 # Check whether the user appended the port
1317 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 if "/" in ingressDevice:
1319 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001320 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001322 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001323 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001324 # Would it make sense to throw an exception and exit
1325 # the test?
1326 return None
andrewonlab36af3822014-11-18 17:48:18 -05001327
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 str( ingressDevice ) + "/" +\
1330 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001331
kelvin-onlabd3b64892015-01-20 13:26:24 -08001332 if "/" in egressDevice:
1333 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001334 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001336 main.log.error( "You must specify the egress port" )
1337 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001338
kelvin8ec71442015-01-15 16:57:00 -08001339 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 str( egressDevice ) + "/" +\
1341 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001342
kelvin-onlab898a6c62015-01-16 14:13:53 -08001343 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001344 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001345 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001346 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001347 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001348 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001349 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001350 # TODO: print out all the options in this message?
1351 main.log.info( "Point-to-point intent installed between " +
1352 str( ingressDevice ) + " and " +
1353 str( egressDevice ) )
1354 match = re.search('id=0x([\da-f]+),', handle)
1355 if match:
1356 return match.group()[3:-1]
1357 else:
1358 main.log.error( "Error, intent ID not found" )
1359 return None
Jon Hallc6793552016-01-19 14:18:37 -08001360 except AssertionError:
1361 main.log.exception( "" )
1362 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001363 except TypeError:
1364 main.log.exception( self.name + ": Object not as expected" )
1365 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001366 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001367 main.log.error( self.name + ": EOF exception found" )
1368 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001369 main.cleanup()
1370 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001371 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001372 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001373 main.cleanup()
1374 main.exit()
1375
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001377 self,
shahshreyac2f97072015-03-19 17:04:29 -07001378 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001380 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001382 ethType="",
1383 ethSrc="",
1384 ethDst="",
1385 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 ipProto="",
1388 ipSrc="",
1389 ipDst="",
1390 tcpSrc="",
1391 tcpDst="",
1392 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001393 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001394 vlanId="",
1395 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001396 """
shahshreyad0c80432014-12-04 16:56:05 -08001397 Note:
shahshreya70622b12015-03-19 17:19:00 -07001398 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001399 is same. That is, all ingress devices include port numbers
1400 with a "/" or all ingress devices could specify device
1401 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001402 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001403 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001404 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001406 Optional:
1407 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001408 * ethSrc: specify ethSrc ( i.e. src mac addr )
1409 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001410 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001412 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001413 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001414 * ipSrc: specify ip source address
1415 * ipDst: specify ip destination address
1416 * tcpSrc: specify tcp source port
1417 * tcpDst: specify tcp destination port
1418 * setEthSrc: action to Rewrite Source MAC Address
1419 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001420 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001421 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001422 Description:
kelvin8ec71442015-01-15 16:57:00 -08001423 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001424 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001425 Returns:
1426 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001427
Jon Halle3f39ff2015-01-13 11:50:53 -08001428 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001429 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001430 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001431 """
shahshreyad0c80432014-12-04 16:56:05 -08001432 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001433 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001434
Jeremy Songsterff553672016-05-12 17:06:23 -07001435 if ethType:
1436 cmd += " --ethType " + str( ethType )
1437 if ethSrc:
1438 cmd += " --ethSrc " + str( ethSrc )
1439 if ethDst:
1440 cmd += " --ethDst " + str( ethDst )
1441 if bandwidth:
1442 cmd += " --bandwidth " + str( bandwidth )
1443 if lambdaAlloc:
1444 cmd += " --lambda "
1445 if ipProto:
1446 cmd += " --ipProto " + str( ipProto )
1447 if ipSrc:
1448 cmd += " --ipSrc " + str( ipSrc )
1449 if ipDst:
1450 cmd += " --ipDst " + str( ipDst )
1451 if tcpSrc:
1452 cmd += " --tcpSrc " + str( tcpSrc )
1453 if tcpDst:
1454 cmd += " --tcpDst " + str( tcpDst )
1455 if setEthSrc:
1456 cmd += " --setEthSrc " + str( setEthSrc )
1457 if setEthDst:
1458 cmd += " --setEthDst " + str( setEthDst )
1459 if vlanId:
1460 cmd += " -v " + str( vlanId )
1461 if setVlan:
1462 cmd += " --setVlan " + str( setVlan )
shahshreyad0c80432014-12-04 16:56:05 -08001463
kelvin8ec71442015-01-15 16:57:00 -08001464 # Check whether the user appended the port
1465 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001466
1467 if portIngressList is None:
1468 for ingressDevice in ingressDeviceList:
1469 if "/" in ingressDevice:
1470 cmd += " " + str( ingressDevice )
1471 else:
1472 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001473 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001474 # TODO: perhaps more meaningful return
1475 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001476 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001477 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001478 for ingressDevice, portIngress in zip( ingressDeviceList,
1479 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001480 cmd += " " + \
1481 str( ingressDevice ) + "/" +\
1482 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001483 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001484 main.log.error( "Device list and port list does not " +
1485 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001486 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 if "/" in egressDevice:
1488 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001489 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001491 main.log.error( "You must specify " +
1492 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001493 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001494
kelvin8ec71442015-01-15 16:57:00 -08001495 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 str( egressDevice ) + "/" +\
1497 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001498 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001499 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001500 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001501 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001502 main.log.error( "Error in adding multipoint-to-singlepoint " +
1503 "intent" )
1504 return None
shahshreyad0c80432014-12-04 16:56:05 -08001505 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001506 match = re.search('id=0x([\da-f]+),', handle)
1507 if match:
1508 return match.group()[3:-1]
1509 else:
1510 main.log.error( "Error, intent ID not found" )
1511 return None
Jon Hallc6793552016-01-19 14:18:37 -08001512 except AssertionError:
1513 main.log.exception( "" )
1514 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001515 except TypeError:
1516 main.log.exception( self.name + ": Object not as expected" )
1517 return None
1518 except pexpect.EOF:
1519 main.log.error( self.name + ": EOF exception found" )
1520 main.log.error( self.name + ": " + self.handle.before )
1521 main.cleanup()
1522 main.exit()
1523 except Exception:
1524 main.log.exception( self.name + ": Uncaught exception!" )
1525 main.cleanup()
1526 main.exit()
1527
1528 def addSinglepointToMultipointIntent(
1529 self,
1530 ingressDevice,
1531 egressDeviceList,
1532 portIngress="",
1533 portEgressList=None,
1534 ethType="",
1535 ethSrc="",
1536 ethDst="",
1537 bandwidth="",
1538 lambdaAlloc=False,
1539 ipProto="",
1540 ipSrc="",
1541 ipDst="",
1542 tcpSrc="",
1543 tcpDst="",
1544 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001545 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001546 vlanId="",
1547 setVlan="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001548 """
1549 Note:
1550 This function assumes the format of all egress devices
1551 is same. That is, all egress devices include port numbers
1552 with a "/" or all egress devices could specify device
1553 ids and port numbers seperately.
1554 Required:
1555 * EgressDeviceList: List of device ids of egress device
1556 ( Atleast 2 eress devices required in the list )
1557 * ingressDevice: device id of ingress device
1558 Optional:
1559 * ethType: specify ethType
1560 * ethSrc: specify ethSrc ( i.e. src mac addr )
1561 * ethDst: specify ethDst ( i.e. dst mac addr )
1562 * bandwidth: specify bandwidth capacity of link
1563 * lambdaAlloc: if True, intent will allocate lambda
1564 for the specified intent
1565 * ipProto: specify ip protocol
1566 * ipSrc: specify ip source address
1567 * ipDst: specify ip destination address
1568 * tcpSrc: specify tcp source port
1569 * tcpDst: specify tcp destination port
1570 * setEthSrc: action to Rewrite Source MAC Address
1571 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001572 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001573 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001574 Description:
1575 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1576 specifying device id's and optional fields
1577 Returns:
1578 A string of the intent id or None on error
1579
1580 NOTE: This function may change depending on the
1581 options developers provide for singlepoint-to-multipoint
1582 intent via cli
1583 """
1584 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001585 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001586
Jeremy Songsterff553672016-05-12 17:06:23 -07001587 if ethType:
1588 cmd += " --ethType " + str( ethType )
1589 if ethSrc:
1590 cmd += " --ethSrc " + str( ethSrc )
1591 if ethDst:
1592 cmd += " --ethDst " + str( ethDst )
1593 if bandwidth:
1594 cmd += " --bandwidth " + str( bandwidth )
1595 if lambdaAlloc:
1596 cmd += " --lambda "
1597 if ipProto:
1598 cmd += " --ipProto " + str( ipProto )
1599 if ipSrc:
1600 cmd += " --ipSrc " + str( ipSrc )
1601 if ipDst:
1602 cmd += " --ipDst " + str( ipDst )
1603 if tcpSrc:
1604 cmd += " --tcpSrc " + str( tcpSrc )
1605 if tcpDst:
1606 cmd += " --tcpDst " + str( tcpDst )
1607 if setEthSrc:
1608 cmd += " --setEthSrc " + str( setEthSrc )
1609 if setEthDst:
1610 cmd += " --setEthDst " + str( setEthDst )
1611 if vlanId:
1612 cmd += " -v " + str( vlanId )
1613 if setVlan:
1614 cmd += " --setVlan " + str( setVlan )
kelvin-onlabb9408212015-04-01 13:34:04 -07001615
1616 # Check whether the user appended the port
1617 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001618
kelvin-onlabb9408212015-04-01 13:34:04 -07001619 if "/" in ingressDevice:
1620 cmd += " " + str( ingressDevice )
1621 else:
1622 if not portIngress:
1623 main.log.error( "You must specify " +
1624 "the Ingress port" )
1625 return main.FALSE
1626
1627 cmd += " " +\
1628 str( ingressDevice ) + "/" +\
1629 str( portIngress )
1630
1631 if portEgressList is None:
1632 for egressDevice in egressDeviceList:
1633 if "/" in egressDevice:
1634 cmd += " " + str( egressDevice )
1635 else:
1636 main.log.error( "You must specify " +
1637 "the egress port" )
1638 # TODO: perhaps more meaningful return
1639 return main.FALSE
1640 else:
1641 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001642 for egressDevice, portEgress in zip( egressDeviceList,
1643 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001644 cmd += " " + \
1645 str( egressDevice ) + "/" +\
1646 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001647 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001648 main.log.error( "Device list and port list does not " +
1649 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001650 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001651 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001652 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001653 # If error, return error message
1654 if re.search( "Error", handle ):
1655 main.log.error( "Error in adding singlepoint-to-multipoint " +
1656 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001657 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001658 else:
1659 match = re.search('id=0x([\da-f]+),', handle)
1660 if match:
1661 return match.group()[3:-1]
1662 else:
1663 main.log.error( "Error, intent ID not found" )
1664 return None
Jon Hallc6793552016-01-19 14:18:37 -08001665 except AssertionError:
1666 main.log.exception( "" )
1667 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001668 except TypeError:
1669 main.log.exception( self.name + ": Object not as expected" )
1670 return None
shahshreyad0c80432014-12-04 16:56:05 -08001671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001672 main.log.error( self.name + ": EOF exception found" )
1673 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001674 main.cleanup()
1675 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001677 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001678 main.cleanup()
1679 main.exit()
1680
Hari Krishna9e232602015-04-13 17:29:08 -07001681 def addMplsIntent(
1682 self,
1683 ingressDevice,
1684 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001685 ingressPort="",
1686 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001687 ethType="",
1688 ethSrc="",
1689 ethDst="",
1690 bandwidth="",
1691 lambdaAlloc=False,
1692 ipProto="",
1693 ipSrc="",
1694 ipDst="",
1695 tcpSrc="",
1696 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001697 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001698 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001699 priority=""):
1700 """
1701 Required:
1702 * ingressDevice: device id of ingress device
1703 * egressDevice: device id of egress device
1704 Optional:
1705 * ethType: specify ethType
1706 * ethSrc: specify ethSrc ( i.e. src mac addr )
1707 * ethDst: specify ethDst ( i.e. dst mac addr )
1708 * bandwidth: specify bandwidth capacity of link
1709 * lambdaAlloc: if True, intent will allocate lambda
1710 for the specified intent
1711 * ipProto: specify ip protocol
1712 * ipSrc: specify ip source address
1713 * ipDst: specify ip destination address
1714 * tcpSrc: specify tcp source port
1715 * tcpDst: specify tcp destination port
1716 * ingressLabel: Ingress MPLS label
1717 * egressLabel: Egress MPLS label
1718 Description:
1719 Adds MPLS intent by
1720 specifying device id's and optional fields
1721 Returns:
1722 A string of the intent id or None on error
1723
1724 NOTE: This function may change depending on the
1725 options developers provide for MPLS
1726 intent via cli
1727 """
1728 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001729 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001730
Jeremy Songsterff553672016-05-12 17:06:23 -07001731 if ethType:
1732 cmd += " --ethType " + str( ethType )
1733 if ethSrc:
1734 cmd += " --ethSrc " + str( ethSrc )
1735 if ethDst:
1736 cmd += " --ethDst " + str( ethDst )
1737 if bandwidth:
1738 cmd += " --bandwidth " + str( bandwidth )
1739 if lambdaAlloc:
1740 cmd += " --lambda "
1741 if ipProto:
1742 cmd += " --ipProto " + str( ipProto )
1743 if ipSrc:
1744 cmd += " --ipSrc " + str( ipSrc )
1745 if ipDst:
1746 cmd += " --ipDst " + str( ipDst )
1747 if tcpSrc:
1748 cmd += " --tcpSrc " + str( tcpSrc )
1749 if tcpDst:
1750 cmd += " --tcpDst " + str( tcpDst )
1751 if ingressLabel:
1752 cmd += " --ingressLabel " + str( ingressLabel )
1753 if egressLabel:
1754 cmd += " --egressLabel " + str( egressLabel )
1755 if priority:
1756 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001757
1758 # Check whether the user appended the port
1759 # or provided it as an input
1760 if "/" in ingressDevice:
1761 cmd += " " + str( ingressDevice )
1762 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001763 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001764 main.log.error( "You must specify the ingress port" )
1765 return None
1766
1767 cmd += " " + \
1768 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001769 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001770
1771 if "/" in egressDevice:
1772 cmd += " " + str( egressDevice )
1773 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001774 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001775 main.log.error( "You must specify the egress port" )
1776 return None
1777
1778 cmd += " " +\
1779 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001780 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001781
1782 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001783 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001784 # If error, return error message
1785 if re.search( "Error", handle ):
1786 main.log.error( "Error in adding mpls intent" )
1787 return None
1788 else:
1789 # TODO: print out all the options in this message?
1790 main.log.info( "MPLS intent installed between " +
1791 str( ingressDevice ) + " and " +
1792 str( egressDevice ) )
1793 match = re.search('id=0x([\da-f]+),', handle)
1794 if match:
1795 return match.group()[3:-1]
1796 else:
1797 main.log.error( "Error, intent ID not found" )
1798 return None
Jon Hallc6793552016-01-19 14:18:37 -08001799 except AssertionError:
1800 main.log.exception( "" )
1801 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001802 except TypeError:
1803 main.log.exception( self.name + ": Object not as expected" )
1804 return None
1805 except pexpect.EOF:
1806 main.log.error( self.name + ": EOF exception found" )
1807 main.log.error( self.name + ": " + self.handle.before )
1808 main.cleanup()
1809 main.exit()
1810 except Exception:
1811 main.log.exception( self.name + ": Uncaught exception!" )
1812 main.cleanup()
1813 main.exit()
1814
Jon Hallefbd9792015-03-05 16:11:36 -08001815 def removeIntent( self, intentId, app='org.onosproject.cli',
1816 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001817 """
shahshreya1c818fc2015-02-26 13:44:08 -08001818 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001819 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001820 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001821 -p or --purge: Purge the intent from the store after removal
1822
Jon Halle3f39ff2015-01-13 11:50:53 -08001823 Returns:
1824 main.False on error and
1825 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001826 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001827 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001828 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001829 if purge:
1830 cmdStr += " -p"
1831 if sync:
1832 cmdStr += " -s"
1833
1834 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001835 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001836 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001837 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001838 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001839 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001840 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001841 # TODO: Should this be main.TRUE
1842 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001843 except AssertionError:
1844 main.log.exception( "" )
1845 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001846 except TypeError:
1847 main.log.exception( self.name + ": Object not as expected" )
1848 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001850 main.log.error( self.name + ": EOF exception found" )
1851 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001852 main.cleanup()
1853 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001855 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001856 main.cleanup()
1857 main.exit()
1858
Jeremy42df2e72016-02-23 16:37:46 -08001859 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1860 """
1861 Description:
1862 Remove all the intents
1863 Optional args:-
1864 -s or --sync: Waits for the removal before returning
1865 -p or --purge: Purge the intent from the store after removal
1866 Returns:
1867 Returns main.TRUE if all intents are removed, otherwise returns
1868 main.FALSE; Returns None for exception
1869 """
1870 try:
1871 cmdStr = "remove-intent"
1872 if purge:
1873 cmdStr += " -p"
1874 if sync:
1875 cmdStr += " -s"
1876
1877 cmdStr += " " + app
1878 handle = self.sendline( cmdStr )
1879 assert "Command not found:" not in handle, handle
1880 if re.search( "Error", handle ):
1881 main.log.error( "Error in removing intent" )
1882 return main.FALSE
1883 else:
1884 return main.TRUE
1885 except AssertionError:
1886 main.log.exception( "" )
1887 return None
1888 except TypeError:
1889 main.log.exception( self.name + ": Object not as expected" )
1890 return None
1891 except pexpect.EOF:
1892 main.log.error( self.name + ": EOF exception found" )
1893 main.log.error( self.name + ": " + self.handle.before )
1894 main.cleanup()
1895 main.exit()
1896 except Exception:
1897 main.log.exception( self.name + ": Uncaught exception!" )
1898 main.cleanup()
1899 main.exit()
1900
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001901 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001902 """
1903 Purges all WITHDRAWN Intents
1904 """
1905 try:
1906 cmdStr = "purge-intents"
1907 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001908 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001909 if re.search( "Error", handle ):
1910 main.log.error( "Error in purging intents" )
1911 return main.FALSE
1912 else:
1913 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001914 except AssertionError:
1915 main.log.exception( "" )
1916 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001917 except TypeError:
1918 main.log.exception( self.name + ": Object not as expected" )
1919 return None
1920 except pexpect.EOF:
1921 main.log.error( self.name + ": EOF exception found" )
1922 main.log.error( self.name + ": " + self.handle.before )
1923 main.cleanup()
1924 main.exit()
1925 except Exception:
1926 main.log.exception( self.name + ": Uncaught exception!" )
1927 main.cleanup()
1928 main.exit()
1929
kelvin-onlabd3b64892015-01-20 13:26:24 -08001930 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001931 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001932 NOTE: This method should be used after installing application:
1933 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001934 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001936 Description:
1937 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001938 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001939 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001940 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001942 cmdStr += " -j"
1943 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001944 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001945 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001946 except AssertionError:
1947 main.log.exception( "" )
1948 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001949 except TypeError:
1950 main.log.exception( self.name + ": Object not as expected" )
1951 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001952 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001953 main.log.error( self.name + ": EOF exception found" )
1954 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001955 main.cleanup()
1956 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001957 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001958 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 main.cleanup()
1960 main.exit()
1961
pingping-lin54b03372015-08-13 14:43:10 -07001962 def ipv4RouteNumber( self ):
1963 """
1964 NOTE: This method should be used after installing application:
1965 onos-app-sdnip
1966 Description:
1967 Obtain the total IPv4 routes number in the system
1968 """
1969 try:
1970 cmdStr = "routes -s -j"
1971 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001972 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001973 jsonResult = json.loads( handle )
1974 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001975 except AssertionError:
1976 main.log.exception( "" )
1977 return None
1978 except ( TypeError, ValueError ):
1979 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001980 return None
1981 except pexpect.EOF:
1982 main.log.error( self.name + ": EOF exception found" )
1983 main.log.error( self.name + ": " + self.handle.before )
1984 main.cleanup()
1985 main.exit()
1986 except Exception:
1987 main.log.exception( self.name + ": Uncaught exception!" )
1988 main.cleanup()
1989 main.exit()
1990
pingping-lin8244a3b2015-09-16 13:36:56 -07001991 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001992 """
andrewonlabe6745342014-10-17 14:29:13 -04001993 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001994 Obtain intents from the ONOS cli.
1995 Optional:
1996 * jsonFormat: Enable output formatting in json, default to True
1997 * summary: Whether only output the intent summary, defaults to False
1998 * type: Only output a certain type of intent. This options is valid
1999 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002000 """
andrewonlabe6745342014-10-17 14:29:13 -04002001 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002002 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002003 if summary:
2004 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002005 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002006 cmdStr += " -j"
2007 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002008 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002009 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002010 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002011 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002012 else:
Jon Hallff566d52016-01-15 14:45:36 -08002013 intentType = ""
2014 # IF we want the summary of a specific intent type
2015 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002016 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002017 if intentType in jsonResult.keys():
2018 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002019 else:
Jon Hallff566d52016-01-15 14:45:36 -08002020 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002021 return handle
2022 else:
2023 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002024 except AssertionError:
2025 main.log.exception( "" )
2026 return None
2027 except ( TypeError, ValueError ):
2028 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002029 return None
2030 except pexpect.EOF:
2031 main.log.error( self.name + ": EOF exception found" )
2032 main.log.error( self.name + ": " + self.handle.before )
2033 main.cleanup()
2034 main.exit()
2035 except Exception:
2036 main.log.exception( self.name + ": Uncaught exception!" )
2037 main.cleanup()
2038 main.exit()
2039
kelvin-onlab54400a92015-02-26 18:05:51 -08002040 def getIntentState(self, intentsId, intentsJson=None):
2041 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002042 Check intent state.
2043 Accepts a single intent ID (string type) or a list of intent IDs.
2044 Returns the state(string type) of the id if a single intent ID is
2045 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08002046 Returns a dictionary with intent IDs as the key and its
2047 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08002048 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08002049 intentId: intent ID (string type)
2050 intentsJson: parsed json object from the onos:intents api
2051 Returns:
2052 state = An intent's state- INSTALL,WITHDRAWN etc.
2053 stateDict = Dictionary of intent's state. intent ID as the keys and
2054 state as the values.
2055 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002056 try:
2057 state = "State is Undefined"
2058 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002059 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002060 else:
Jon Hallc6793552016-01-19 14:18:37 -08002061 rawJson = intentsJson
2062 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002063 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002064 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002065 if intentsId == intent[ 'id' ]:
2066 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002067 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002068 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2069 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002071 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002072 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002073 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002074 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002075 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002076 if intentsId[ i ] == intents[ 'id' ]:
2077 stateDict[ 'state' ] = intents[ 'state' ]
2078 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002079 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002080 break
Jon Hallefbd9792015-03-05 16:11:36 -08002081 if len( intentsId ) != len( dictList ):
2082 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002083 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002084 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002085 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002086 return None
Jon Hallc6793552016-01-19 14:18:37 -08002087 except ( TypeError, ValueError ):
2088 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 return None
2090 except pexpect.EOF:
2091 main.log.error( self.name + ": EOF exception found" )
2092 main.log.error( self.name + ": " + self.handle.before )
2093 main.cleanup()
2094 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002095 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002096 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002097 main.cleanup()
2098 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002099
kelvin-onlabf512e942015-06-08 19:42:59 -07002100 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002101 """
2102 Description:
2103 Check intents state
2104 Required:
2105 intentsId - List of intents ID to be checked
2106 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002107 expectedState - Check the expected state(s) of each intents
2108 state in the list.
2109 *NOTE: You can pass in a list of expected state,
2110 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002111 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002112 Returns main.TRUE only if all intent are the same as expected states
2113 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002114 """
2115 try:
2116 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002117 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002119 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002120 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002121 "getting intents state" )
2122 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002123
2124 if isinstance( expectedState, types.StringType ):
2125 for intents in intentsDict:
2126 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002127 main.log.debug( self.name + " : Intent ID - " +
2128 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 " actual state = " +
2130 intents.get( 'state' )
2131 + " does not equal expected state = "
2132 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002133 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002134
2135 elif isinstance( expectedState, types.ListType ):
2136 for intents in intentsDict:
2137 if not any( state == intents.get( 'state' ) for state in
2138 expectedState ):
2139 main.log.debug( self.name + " : Intent ID - " +
2140 intents.get( 'id' ) +
2141 " actual state = " +
2142 intents.get( 'state' ) +
2143 " does not equal expected states = "
2144 + str( expectedState ) )
2145 returnValue = main.FALSE
2146
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002147 if returnValue == main.TRUE:
2148 main.log.info( self.name + ": All " +
2149 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002150 " intents are in " + str( expectedState ) +
2151 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002152 return returnValue
2153 except TypeError:
2154 main.log.exception( self.name + ": Object not as expected" )
2155 return None
2156 except pexpect.EOF:
2157 main.log.error( self.name + ": EOF exception found" )
2158 main.log.error( self.name + ": " + self.handle.before )
2159 main.cleanup()
2160 main.exit()
2161 except Exception:
2162 main.log.exception( self.name + ": Uncaught exception!" )
2163 main.cleanup()
2164 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002165
GlennRCed771242016-01-13 17:02:47 -08002166 def checkIntentSummary( self, timeout=60 ):
2167 """
2168 Description:
2169 Check the number of installed intents.
2170 Optional:
2171 timeout - the timeout for pexcept
2172 Return:
2173 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2174 , otherwise, returns main.FALSE.
2175 """
2176
2177 try:
2178 cmd = "intents -s -j"
2179
2180 # Check response if something wrong
2181 response = self.sendline( cmd, timeout=timeout )
2182 if response == None:
2183 return main.False
2184 response = json.loads( response )
2185
2186 # get total and installed number, see if they are match
2187 allState = response.get( 'all' )
2188 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002189 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002190 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002191 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002192 return main.FALSE
2193
Jon Hallc6793552016-01-19 14:18:37 -08002194 except ( TypeError, ValueError ):
2195 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002196 return None
2197 except pexpect.EOF:
2198 main.log.error( self.name + ": EOF exception found" )
2199 main.log.error( self.name + ": " + self.handle.before )
2200 main.cleanup()
2201 main.exit()
2202 except Exception:
2203 main.log.exception( self.name + ": Uncaught exception!" )
2204 main.cleanup()
2205 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002206 except pexpect.TIMEOUT:
2207 main.log.error( self.name + ": ONOS timeout" )
2208 return None
GlennRCed771242016-01-13 17:02:47 -08002209
YPZhangebf9eb52016-05-12 15:20:24 -07002210 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002211 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002212 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002214 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002215 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002216 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002217 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002218 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002219 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002220 cmdStr += " -j "
2221 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002222 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002223 assert "Command not found:" not in handle, handle
2224 if re.search( "Error:", handle ):
2225 main.log.error( self.name + ": flows() response: " +
2226 str( handle ) )
2227 return handle
2228 except AssertionError:
2229 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002230 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002231 except TypeError:
2232 main.log.exception( self.name + ": Object not as expected" )
2233 return None
Jon Hallc6793552016-01-19 14:18:37 -08002234 except pexpect.TIMEOUT:
2235 main.log.error( self.name + ": ONOS timeout" )
2236 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002237 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002238 main.log.error( self.name + ": EOF exception found" )
2239 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002240 main.cleanup()
2241 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002242 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002243 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002244 main.cleanup()
2245 main.exit()
2246
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002247 def checkFlowCount(self, min=0, timeout=60 ):
2248 count = int(self.getTotalFlowsNum( timeout=timeout ))
2249 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002250
YPZhangebf9eb52016-05-12 15:20:24 -07002251 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002252 """
2253 Description:
GlennRCed771242016-01-13 17:02:47 -08002254 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002255 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2256 if the count of those states is 0, which means all current flows
2257 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002258 Optional:
GlennRCed771242016-01-13 17:02:47 -08002259 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002260 Return:
2261 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002262 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002263 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002264 """
2265 try:
GlennRCed771242016-01-13 17:02:47 -08002266 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2267 checkedStates = []
2268 statesCount = [0, 0, 0, 0]
2269 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002270 rawFlows = self.flows( state=s, timeout = timeout )
2271 checkedStates.append( json.loads( rawFlows ) )
2272 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002273 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002274 try:
2275 statesCount[i] += int( c.get( "flowCount" ) )
2276 except TypeError:
2277 main.log.exception( "Json object not as expected" )
2278 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002279
GlennRCed771242016-01-13 17:02:47 -08002280 # We want to count PENDING_ADD if isPENDING is true
2281 if isPENDING:
2282 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2283 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002284 else:
GlennRCed771242016-01-13 17:02:47 -08002285 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2286 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002287 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002288 except ( TypeError, ValueError ):
2289 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002290 return None
2291 except pexpect.EOF:
2292 main.log.error( self.name + ": EOF exception found" )
2293 main.log.error( self.name + ": " + self.handle.before )
2294 main.cleanup()
2295 main.exit()
2296 except Exception:
2297 main.log.exception( self.name + ": Uncaught exception!" )
2298 main.cleanup()
2299 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002300 except pexpect.TIMEOUT:
2301 main.log.error( self.name + ": ONOS timeout" )
2302 return None
2303
kelvin-onlab4df89f22015-04-13 18:10:23 -07002304
GlennRCed771242016-01-13 17:02:47 -08002305 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002306 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002307 """
andrewonlab87852b02014-11-19 18:44:19 -05002308 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002309 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002310 a specific point-to-point intent definition
2311 Required:
GlennRCed771242016-01-13 17:02:47 -08002312 * ingress: specify source dpid
2313 * egress: specify destination dpid
2314 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002315 Optional:
GlennRCed771242016-01-13 17:02:47 -08002316 * offset: the keyOffset is where the next batch of intents
2317 will be installed
2318 Returns: If failed to push test intents, it will returen None,
2319 if successful, return true.
2320 Timeout expection will return None,
2321 TypeError will return false
2322 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002323 """
andrewonlab87852b02014-11-19 18:44:19 -05002324 try:
GlennRCed771242016-01-13 17:02:47 -08002325 if background:
2326 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002327 else:
GlennRCed771242016-01-13 17:02:47 -08002328 back = ""
2329 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002330 ingress,
2331 egress,
2332 batchSize,
2333 offset,
2334 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002335 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002336 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002337 main.log.info( response )
2338 if response == None:
2339 return None
2340
2341 # TODO: We should handle if there is failure in installation
2342 return main.TRUE
2343
Jon Hallc6793552016-01-19 14:18:37 -08002344 except AssertionError:
2345 main.log.exception( "" )
2346 return None
GlennRCed771242016-01-13 17:02:47 -08002347 except pexpect.TIMEOUT:
2348 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002349 return None
andrewonlab87852b02014-11-19 18:44:19 -05002350 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002351 main.log.error( self.name + ": EOF exception found" )
2352 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002353 main.cleanup()
2354 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002355 except TypeError:
2356 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002357 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002358 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002359 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002360 main.cleanup()
2361 main.exit()
2362
YPZhangebf9eb52016-05-12 15:20:24 -07002363 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002364 """
2365 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002366 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002367 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002368 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002369 """
YPZhange3109a72016-02-02 11:25:37 -08002370
YPZhangb5d3f832016-01-23 22:54:26 -08002371 try:
YPZhange3109a72016-02-02 11:25:37 -08002372 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002373 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002374 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002375
2376 if totalFlows == None:
2377 # if timeout, we will get total number of all flows, and subtract other states
2378 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2379 checkedStates = []
2380 totalFlows = 0
2381 statesCount = [0, 0, 0, 0]
2382
2383 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002384 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002385 totalFlows = int( response.get("flows") )
2386
2387 for s in states:
2388 rawFlows = self.flows( state=s, timeout = timeout )
2389 if rawFlows == None:
2390 # if timeout, return the total flows number from summary command
2391 return totalFlows
2392 checkedStates.append( json.loads( rawFlows ) )
2393
2394 # Calculate ADDED flows number, equal total subtracts others
2395 for i in range( len( states ) ):
2396 for c in checkedStates[i]:
2397 try:
2398 statesCount[i] += int( c.get( "flowCount" ) )
2399 except TypeError:
2400 main.log.exception( "Json object not as expected" )
2401 totalFlows = totalFlows - int( statesCount[i] )
2402 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2403
2404 return totalFlows
2405
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002406 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002407
YPZhangb5d3f832016-01-23 22:54:26 -08002408 except TypeError:
2409 main.log.exception( self.name + ": Object not as expected" )
2410 return None
2411 except pexpect.EOF:
2412 main.log.error( self.name + ": EOF exception found" )
2413 main.log.error( self.name + ": " + self.handle.before )
2414 main.cleanup()
2415 main.exit()
2416 except Exception:
2417 main.log.exception( self.name + ": Uncaught exception!" )
2418 main.cleanup()
2419 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002420 except pexpect.TIMEOUT:
2421 main.log.error( self.name + ": ONOS timeout" )
2422 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002423
YPZhangebf9eb52016-05-12 15:20:24 -07002424 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002425 """
2426 Description:
2427 Get the total number of intents, include every states.
2428 Return:
2429 The number of intents
2430 """
2431 try:
2432 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002433 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002434 if response == None:
2435 return -1
2436 response = json.loads( response )
2437 return int( response.get("intents") )
2438 except TypeError:
2439 main.log.exception( self.name + ": Object not as expected" )
2440 return None
2441 except pexpect.EOF:
2442 main.log.error( self.name + ": EOF exception found" )
2443 main.log.error( self.name + ": " + self.handle.before )
2444 main.cleanup()
2445 main.exit()
2446 except Exception:
2447 main.log.exception( self.name + ": Uncaught exception!" )
2448 main.cleanup()
2449 main.exit()
2450
kelvin-onlabd3b64892015-01-20 13:26:24 -08002451 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002452 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002453 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002454 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002455 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002456 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002457 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002458 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002459 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002460 cmdStr += " -j"
2461 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002462 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002463 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002464 except AssertionError:
2465 main.log.exception( "" )
2466 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002467 except TypeError:
2468 main.log.exception( self.name + ": Object not as expected" )
2469 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002471 main.log.error( self.name + ": EOF exception found" )
2472 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002473 main.cleanup()
2474 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002475 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002476 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002477 main.cleanup()
2478 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002479
kelvin-onlabd3b64892015-01-20 13:26:24 -08002480 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002481 """
2482 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002483 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002485 """
andrewonlab867212a2014-10-22 20:13:38 -04002486 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002487 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002489 cmdStr += " -j"
2490 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002491 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002492 if handle:
2493 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002494 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002495 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002496 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002497 else:
2498 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002499 except AssertionError:
2500 main.log.exception( "" )
2501 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002502 except TypeError:
2503 main.log.exception( self.name + ": Object not as expected" )
2504 return None
andrewonlab867212a2014-10-22 20:13:38 -04002505 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002506 main.log.error( self.name + ": EOF exception found" )
2507 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002508 main.cleanup()
2509 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002510 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002511 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002512 main.cleanup()
2513 main.exit()
2514
kelvin8ec71442015-01-15 16:57:00 -08002515 # Wrapper functions ****************
2516 # Wrapper functions use existing driver
2517 # functions and extends their use case.
2518 # For example, we may use the output of
2519 # a normal driver function, and parse it
2520 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002521
kelvin-onlabd3b64892015-01-20 13:26:24 -08002522 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002523 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002524 Description:
2525 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002526 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002527 try:
kelvin8ec71442015-01-15 16:57:00 -08002528 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002529 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002531
kelvin8ec71442015-01-15 16:57:00 -08002532 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002533 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2534 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002535 match = re.search('id=0x([\da-f]+),', intents)
2536 if match:
2537 tmpId = match.group()[3:-1]
2538 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002539 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002540
Jon Halld4d4b372015-01-28 16:02:41 -08002541 except TypeError:
2542 main.log.exception( self.name + ": Object not as expected" )
2543 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002547 main.cleanup()
2548 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002549 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002550 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002551 main.cleanup()
2552 main.exit()
2553
Jon Hall30b82fa2015-03-04 17:15:43 -08002554 def FlowAddedCount( self, deviceId ):
2555 """
2556 Determine the number of flow rules for the given device id that are
2557 in the added state
2558 """
2559 try:
2560 cmdStr = "flows any " + str( deviceId ) + " | " +\
2561 "grep 'state=ADDED' | wc -l"
2562 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002563 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002564 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002565 except AssertionError:
2566 main.log.exception( "" )
2567 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002568 except pexpect.EOF:
2569 main.log.error( self.name + ": EOF exception found" )
2570 main.log.error( self.name + ": " + self.handle.before )
2571 main.cleanup()
2572 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002573 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002574 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002575 main.cleanup()
2576 main.exit()
2577
kelvin-onlabd3b64892015-01-20 13:26:24 -08002578 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002579 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002580 Use 'devices' function to obtain list of all devices
2581 and parse the result to obtain a list of all device
2582 id's. Returns this list. Returns empty list if no
2583 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002584 List is ordered sequentially
2585
andrewonlab3e15ead2014-10-15 14:21:34 -04002586 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002587 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002588 the ids. By obtaining the list of device ids on the fly,
2589 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002590 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002591 try:
kelvin8ec71442015-01-15 16:57:00 -08002592 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 devicesStr = self.devices( jsonFormat=False )
2594 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002595
kelvin-onlabd3b64892015-01-20 13:26:24 -08002596 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002597 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 return idList
kelvin8ec71442015-01-15 16:57:00 -08002599
2600 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002602 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002604 # Split list further into arguments before and after string
2605 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002606 # append to idList
2607 for arg in tempList:
2608 idList.append( arg.split( "id=" )[ 1 ] )
2609 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002610
Jon Halld4d4b372015-01-28 16:02:41 -08002611 except TypeError:
2612 main.log.exception( self.name + ": Object not as expected" )
2613 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002615 main.log.error( self.name + ": EOF exception found" )
2616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002617 main.cleanup()
2618 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002619 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002621 main.cleanup()
2622 main.exit()
2623
kelvin-onlabd3b64892015-01-20 13:26:24 -08002624 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002625 """
andrewonlab7c211572014-10-15 16:45:20 -04002626 Uses 'nodes' function to obtain list of all nodes
2627 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002628 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002629 Returns:
2630 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002631 """
andrewonlab7c211572014-10-15 16:45:20 -04002632 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002633 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002634 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002635 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002636 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002637 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002638 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002639 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002640 nodesJson = json.loads( nodesStr )
2641 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002642 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002643 except ( TypeError, ValueError ):
2644 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002645 return None
andrewonlab7c211572014-10-15 16:45:20 -04002646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002649 main.cleanup()
2650 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002651 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002652 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002653 main.cleanup()
2654 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002655
kelvin-onlabd3b64892015-01-20 13:26:24 -08002656 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002657 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002658 Return the first device from the devices api whose 'id' contains 'dpid'
2659 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002660 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002661 try:
kelvin8ec71442015-01-15 16:57:00 -08002662 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002663 return None
2664 else:
kelvin8ec71442015-01-15 16:57:00 -08002665 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002666 rawDevices = self.devices()
2667 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002668 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002669 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002670 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2671 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002672 return device
2673 return None
Jon Hallc6793552016-01-19 14:18:37 -08002674 except ( TypeError, ValueError ):
2675 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002676 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002677 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002678 main.log.error( self.name + ": EOF exception found" )
2679 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002680 main.cleanup()
2681 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002682 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002683 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002684 main.cleanup()
2685 main.exit()
2686
You Wang24139872016-05-03 11:48:47 -07002687 def getTopology( self, topologyOutput ):
2688 """
2689 Definition:
2690 Loads a json topology output
2691 Return:
2692 topology = current ONOS topology
2693 """
2694 import json
2695 try:
2696 # either onos:topology or 'topology' will work in CLI
2697 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002698 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002699 return topology
2700 except pexpect.EOF:
2701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
2703 main.cleanup()
2704 main.exit()
2705 except Exception:
2706 main.log.exception( self.name + ": Uncaught exception!" )
2707 main.cleanup()
2708 main.exit()
2709
2710 def checkStatus(
2711 self,
2712 topologyResult,
2713 numoswitch,
2714 numolink,
2715 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002716 """
Jon Hallefbd9792015-03-05 16:11:36 -08002717 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002718 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002719 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002720
You Wang24139872016-05-03 11:48:47 -07002721 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002722 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002723 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002724 logLevel = level to log to.
2725 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002726
Jon Hallefbd9792015-03-05 16:11:36 -08002727 Returns: main.TRUE if the number of switches and links are correct,
2728 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002729 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002730 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002731 try:
You Wang24139872016-05-03 11:48:47 -07002732 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002733 if topology == {}:
2734 return main.ERROR
2735 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002736 # Is the number of switches is what we expected
2737 devices = topology.get( 'devices', False )
2738 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002739 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002740 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002741 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002742 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002743 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002744 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002745 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002746 output = output + "The number of links and switches match "\
2747 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002748 result = main.TRUE
2749 else:
You Wang24139872016-05-03 11:48:47 -07002750 output = output + \
2751 "The number of links and switches does not match " + \
2752 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002753 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002754 output = output + "\n ONOS sees %i devices" % int( devices )
2755 output = output + " (%i expected) " % int( numoswitch )
2756 output = output + "and %i links " % int( links )
2757 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002758 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002759 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002760 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002761 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002762 else:
You Wang24139872016-05-03 11:48:47 -07002763 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002764 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002768 main.cleanup()
2769 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002772 main.cleanup()
2773 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002774
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002776 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002777 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 deviceId must be the id of a device as seen in the onos devices command
2779 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002780 role must be either master, standby, or none
2781
Jon Halle3f39ff2015-01-13 11:50:53 -08002782 Returns:
2783 main.TRUE or main.FALSE based on argument verification and
2784 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002785 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002786 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002787 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002788 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 cmdStr = "device-role " +\
2790 str( deviceId ) + " " +\
2791 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002792 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002794 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002795 if re.search( "Error", handle ):
2796 # end color output to escape any colours
2797 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002798 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002799 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002800 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002801 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002802 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002803 main.log.error( "Invalid 'role' given to device_role(). " +
2804 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002805 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002806 except AssertionError:
2807 main.log.exception( "" )
2808 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002809 except TypeError:
2810 main.log.exception( self.name + ": Object not as expected" )
2811 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002813 main.log.error( self.name + ": EOF exception found" )
2814 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002815 main.cleanup()
2816 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002818 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002819 main.cleanup()
2820 main.exit()
2821
kelvin-onlabd3b64892015-01-20 13:26:24 -08002822 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002823 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002824 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002825 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002827 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002828 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002829 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002830 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 cmdStr += " -j"
2832 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002833 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002834 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002835 except AssertionError:
2836 main.log.exception( "" )
2837 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002838 except TypeError:
2839 main.log.exception( self.name + ": Object not as expected" )
2840 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002841 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002842 main.log.error( self.name + ": EOF exception found" )
2843 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002844 main.cleanup()
2845 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002846 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002847 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002848 main.cleanup()
2849 main.exit()
2850
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002852 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002853 CLI command to get the current leader for the Election test application
2854 NOTE: Requires installation of the onos-app-election feature
2855 Returns: Node IP of the leader if one exists
2856 None if none exists
2857 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002858 """
Jon Hall94fd0472014-12-08 11:52:42 -08002859 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 cmdStr = "election-test-leader"
2861 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002862 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002863 # Leader
2864 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002865 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002866 nodeSearch = re.search( leaderPattern, response )
2867 if nodeSearch:
2868 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002869 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002871 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002872 # no leader
2873 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002874 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002875 nullSearch = re.search( nullPattern, response )
2876 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002877 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002878 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002879 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002880 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002881 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002882 if re.search( errorPattern, response ):
2883 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002884 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002885 return main.FALSE
2886 else:
Jon Hall390696c2015-05-05 17:13:41 -07002887 main.log.error( "Error in electionTestLeader on " + self.name +
2888 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002889 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002890 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002891 except AssertionError:
2892 main.log.exception( "" )
2893 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002894 except TypeError:
2895 main.log.exception( self.name + ": Object not as expected" )
2896 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002898 main.log.error( self.name + ": EOF exception found" )
2899 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002900 main.cleanup()
2901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002903 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002904 main.cleanup()
2905 main.exit()
2906
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002908 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002909 CLI command to run for leadership of the Election test application.
2910 NOTE: Requires installation of the onos-app-election feature
2911 Returns: Main.TRUE on success
2912 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002913 """
Jon Hall94fd0472014-12-08 11:52:42 -08002914 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002915 cmdStr = "election-test-run"
2916 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002917 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002918 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002919 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002920 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002921 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002922 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002923 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002924 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002925 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002926 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002927 errorPattern = "Command\snot\sfound"
2928 if re.search( errorPattern, response ):
2929 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002930 return main.FALSE
2931 else:
Jon Hall390696c2015-05-05 17:13:41 -07002932 main.log.error( "Error in electionTestRun on " + self.name +
2933 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002934 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002935 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002936 except AssertionError:
2937 main.log.exception( "" )
2938 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002939 except TypeError:
2940 main.log.exception( self.name + ": Object not as expected" )
2941 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002943 main.log.error( self.name + ": EOF exception found" )
2944 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002945 main.cleanup()
2946 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002947 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002948 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002949 main.cleanup()
2950 main.exit()
2951
kelvin-onlabd3b64892015-01-20 13:26:24 -08002952 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002953 """
Jon Hall94fd0472014-12-08 11:52:42 -08002954 * CLI command to withdraw the local node from leadership election for
2955 * the Election test application.
2956 #NOTE: Requires installation of the onos-app-election feature
2957 Returns: Main.TRUE on success
2958 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002959 """
Jon Hall94fd0472014-12-08 11:52:42 -08002960 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002961 cmdStr = "election-test-withdraw"
2962 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002963 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002964 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002965 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002966 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002967 if re.search( successPattern, response ):
2968 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002969 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002970 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002971 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002972 errorPattern = "Command\snot\sfound"
2973 if re.search( errorPattern, response ):
2974 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002975 return main.FALSE
2976 else:
Jon Hall390696c2015-05-05 17:13:41 -07002977 main.log.error( "Error in electionTestWithdraw on " +
2978 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002979 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002980 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002981 except AssertionError:
2982 main.log.exception( "" )
2983 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002984 except TypeError:
2985 main.log.exception( self.name + ": Object not as expected" )
2986 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002987 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002988 main.log.error( self.name + ": EOF exception found" )
2989 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002990 main.cleanup()
2991 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002992 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002993 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002994 main.cleanup()
2995 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002996
kelvin8ec71442015-01-15 16:57:00 -08002997 def getDevicePortsEnabledCount( self, dpid ):
2998 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002999 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003000 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003001 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003002 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003003 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3004 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003005 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003006 if re.search( "No such device", output ):
3007 main.log.error( "Error in getting ports" )
3008 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003009 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003010 return output
Jon Hallc6793552016-01-19 14:18:37 -08003011 except AssertionError:
3012 main.log.exception( "" )
3013 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003014 except TypeError:
3015 main.log.exception( self.name + ": Object not as expected" )
3016 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003017 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003018 main.log.error( self.name + ": EOF exception found" )
3019 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003020 main.cleanup()
3021 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003022 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003023 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003024 main.cleanup()
3025 main.exit()
3026
kelvin8ec71442015-01-15 16:57:00 -08003027 def getDeviceLinksActiveCount( self, dpid ):
3028 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003029 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003030 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003031 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003033 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3034 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003035 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003036 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 main.log.error( "Error in getting ports " )
3038 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003039 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 return output
Jon Hallc6793552016-01-19 14:18:37 -08003041 except AssertionError:
3042 main.log.exception( "" )
3043 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003044 except TypeError:
3045 main.log.exception( self.name + ": Object not as expected" )
3046 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003048 main.log.error( self.name + ": EOF exception found" )
3049 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003050 main.cleanup()
3051 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003052 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003053 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003054 main.cleanup()
3055 main.exit()
3056
kelvin8ec71442015-01-15 16:57:00 -08003057 def getAllIntentIds( self ):
3058 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003059 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003060 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003061 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003062 cmdStr = "onos:intents | grep id="
3063 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003064 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003065 if re.search( "Error", output ):
3066 main.log.error( "Error in getting ports" )
3067 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003068 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003069 return output
Jon Hallc6793552016-01-19 14:18:37 -08003070 except AssertionError:
3071 main.log.exception( "" )
3072 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003073 except TypeError:
3074 main.log.exception( self.name + ": Object not as expected" )
3075 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003076 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003077 main.log.error( self.name + ": EOF exception found" )
3078 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003079 main.cleanup()
3080 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003081 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003082 main.log.exception( self.name + ": Uncaught exception!" )
3083 main.cleanup()
3084 main.exit()
3085
Jon Hall73509952015-02-24 16:42:56 -08003086 def intentSummary( self ):
3087 """
Jon Hallefbd9792015-03-05 16:11:36 -08003088 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003089 """
3090 try:
3091 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003092 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003093 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003094 states.append( intent.get( 'state', None ) )
3095 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003096 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003097 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003098 except ( TypeError, ValueError ):
3099 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003100 return None
3101 except pexpect.EOF:
3102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
3104 main.cleanup()
3105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003106 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003107 main.log.exception( self.name + ": Uncaught exception!" )
3108 main.cleanup()
3109 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003110
Jon Hall61282e32015-03-19 11:34:11 -07003111 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003112 """
3113 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003114 Optional argument:
3115 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003116 """
Jon Hall63604932015-02-26 17:09:50 -08003117 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003118 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003119 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003120 cmdStr += " -j"
3121 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003122 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003123 return output
Jon Hallc6793552016-01-19 14:18:37 -08003124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
Jon Hall63604932015-02-26 17:09:50 -08003127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003130 except pexpect.EOF:
3131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
3133 main.cleanup()
3134 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003135 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003136 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003137 main.cleanup()
3138 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003139
acsmarsa4a4d1e2015-07-10 16:01:24 -07003140 def leaderCandidates( self, jsonFormat=True ):
3141 """
3142 Returns the output of the leaders -c command.
3143 Optional argument:
3144 * jsonFormat - boolean indicating if you want output in json
3145 """
3146 try:
3147 cmdStr = "onos:leaders -c"
3148 if jsonFormat:
3149 cmdStr += " -j"
3150 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003151 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003152 return output
Jon Hallc6793552016-01-19 14:18:37 -08003153 except AssertionError:
3154 main.log.exception( "" )
3155 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003156 except TypeError:
3157 main.log.exception( self.name + ": Object not as expected" )
3158 return None
3159 except pexpect.EOF:
3160 main.log.error( self.name + ": EOF exception found" )
3161 main.log.error( self.name + ": " + self.handle.before )
3162 main.cleanup()
3163 main.exit()
3164 except Exception:
3165 main.log.exception( self.name + ": Uncaught exception!" )
3166 main.cleanup()
3167 main.exit()
3168
Jon Hallc6793552016-01-19 14:18:37 -08003169 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003170 """
3171 Returns a list in format [leader,candidate1,candidate2,...] for a given
3172 topic parameter and an empty list if the topic doesn't exist
3173 If no leader is elected leader in the returned list will be "none"
3174 Returns None if there is a type error processing the json object
3175 """
3176 try:
Jon Hall6e709752016-02-01 13:38:46 -08003177 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003178 rawOutput = self.sendline( cmdStr )
3179 assert "Command not found:" not in rawOutput, rawOutput
3180 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003181 results = []
3182 for dict in output:
3183 if dict["topic"] == topic:
3184 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003185 candidates = re.split( ", ", dict["candidates"][1:-1] )
3186 results.append( leader )
3187 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003188 return results
Jon Hallc6793552016-01-19 14:18:37 -08003189 except AssertionError:
3190 main.log.exception( "" )
3191 return None
3192 except ( TypeError, ValueError ):
3193 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003194 return None
3195 except pexpect.EOF:
3196 main.log.error( self.name + ": EOF exception found" )
3197 main.log.error( self.name + ": " + self.handle.before )
3198 main.cleanup()
3199 main.exit()
3200 except Exception:
3201 main.log.exception( self.name + ": Uncaught exception!" )
3202 main.cleanup()
3203 main.exit()
3204
Jon Hall61282e32015-03-19 11:34:11 -07003205 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003206 """
3207 Returns the output of the intent Pending map.
3208 """
Jon Hall63604932015-02-26 17:09:50 -08003209 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003210 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003211 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003212 cmdStr += " -j"
3213 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003214 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003215 return output
Jon Hallc6793552016-01-19 14:18:37 -08003216 except AssertionError:
3217 main.log.exception( "" )
3218 return None
Jon Hall63604932015-02-26 17:09:50 -08003219 except TypeError:
3220 main.log.exception( self.name + ": Object not as expected" )
3221 return None
3222 except pexpect.EOF:
3223 main.log.error( self.name + ": EOF exception found" )
3224 main.log.error( self.name + ": " + self.handle.before )
3225 main.cleanup()
3226 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003227 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003228 main.log.exception( self.name + ": Uncaught exception!" )
3229 main.cleanup()
3230 main.exit()
3231
Jon Hall61282e32015-03-19 11:34:11 -07003232 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003233 """
3234 Returns the output of the raft partitions command for ONOS.
3235 """
Jon Hall61282e32015-03-19 11:34:11 -07003236 # Sample JSON
3237 # {
3238 # "leader": "tcp://10.128.30.11:7238",
3239 # "members": [
3240 # "tcp://10.128.30.11:7238",
3241 # "tcp://10.128.30.17:7238",
3242 # "tcp://10.128.30.13:7238",
3243 # ],
3244 # "name": "p1",
3245 # "term": 3
3246 # },
Jon Hall63604932015-02-26 17:09:50 -08003247 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003248 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003249 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003250 cmdStr += " -j"
3251 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003252 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003253 return output
Jon Hallc6793552016-01-19 14:18:37 -08003254 except AssertionError:
3255 main.log.exception( "" )
3256 return None
Jon Hall63604932015-02-26 17:09:50 -08003257 except TypeError:
3258 main.log.exception( self.name + ": Object not as expected" )
3259 return None
3260 except pexpect.EOF:
3261 main.log.error( self.name + ": EOF exception found" )
3262 main.log.error( self.name + ": " + self.handle.before )
3263 main.cleanup()
3264 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003265 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003266 main.log.exception( self.name + ": Uncaught exception!" )
3267 main.cleanup()
3268 main.exit()
3269
Jon Hallbe379602015-03-24 13:39:32 -07003270 def apps( self, jsonFormat=True ):
3271 """
3272 Returns the output of the apps command for ONOS. This command lists
3273 information about installed ONOS applications
3274 """
3275 # Sample JSON object
3276 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3277 # "description":"ONOS OpenFlow protocol southbound providers",
3278 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3279 # "features":"[onos-openflow]","state":"ACTIVE"}]
3280 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003281 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003282 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003283 cmdStr += " -j"
3284 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003285 assert "Command not found:" not in output, output
3286 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003287 return output
Jon Hallbe379602015-03-24 13:39:32 -07003288 # FIXME: look at specific exceptions/Errors
3289 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003290 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003291 return None
3292 except TypeError:
3293 main.log.exception( self.name + ": Object not as expected" )
3294 return None
3295 except pexpect.EOF:
3296 main.log.error( self.name + ": EOF exception found" )
3297 main.log.error( self.name + ": " + self.handle.before )
3298 main.cleanup()
3299 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003300 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003301 main.log.exception( self.name + ": Uncaught exception!" )
3302 main.cleanup()
3303 main.exit()
3304
Jon Hall146f1522015-03-24 15:33:24 -07003305 def appStatus( self, appName ):
3306 """
3307 Uses the onos:apps cli command to return the status of an application.
3308 Returns:
3309 "ACTIVE" - If app is installed and activated
3310 "INSTALLED" - If app is installed and deactivated
3311 "UNINSTALLED" - If app is not installed
3312 None - on error
3313 """
Jon Hall146f1522015-03-24 15:33:24 -07003314 try:
3315 if not isinstance( appName, types.StringType ):
3316 main.log.error( self.name + ".appStatus(): appName must be" +
3317 " a string" )
3318 return None
3319 output = self.apps( jsonFormat=True )
3320 appsJson = json.loads( output )
3321 state = None
3322 for app in appsJson:
3323 if appName == app.get('name'):
3324 state = app.get('state')
3325 break
3326 if state == "ACTIVE" or state == "INSTALLED":
3327 return state
3328 elif state is None:
3329 return "UNINSTALLED"
3330 elif state:
3331 main.log.error( "Unexpected state from 'onos:apps': " +
3332 str( state ) )
3333 return state
Jon Hallc6793552016-01-19 14:18:37 -08003334 except ( TypeError, ValueError ):
3335 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003336 return None
3337 except pexpect.EOF:
3338 main.log.error( self.name + ": EOF exception found" )
3339 main.log.error( self.name + ": " + self.handle.before )
3340 main.cleanup()
3341 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003342 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003343 main.log.exception( self.name + ": Uncaught exception!" )
3344 main.cleanup()
3345 main.exit()
3346
Jon Hallbe379602015-03-24 13:39:32 -07003347 def app( self, appName, option ):
3348 """
3349 Interacts with the app command for ONOS. This command manages
3350 application inventory.
3351 """
Jon Hallbe379602015-03-24 13:39:32 -07003352 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003353 # Validate argument types
3354 valid = True
3355 if not isinstance( appName, types.StringType ):
3356 main.log.error( self.name + ".app(): appName must be a " +
3357 "string" )
3358 valid = False
3359 if not isinstance( option, types.StringType ):
3360 main.log.error( self.name + ".app(): option must be a string" )
3361 valid = False
3362 if not valid:
3363 return main.FALSE
3364 # Validate Option
3365 option = option.lower()
3366 # NOTE: Install may become a valid option
3367 if option == "activate":
3368 pass
3369 elif option == "deactivate":
3370 pass
3371 elif option == "uninstall":
3372 pass
3373 else:
3374 # Invalid option
3375 main.log.error( "The ONOS app command argument only takes " +
3376 "the values: (activate|deactivate|uninstall)" +
3377 "; was given '" + option + "'")
3378 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003379 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003380 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003381 if "Error executing command" in output:
3382 main.log.error( "Error in processing onos:app command: " +
3383 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003384 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003385 elif "No such application" in output:
3386 main.log.error( "The application '" + appName +
3387 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003388 return main.FALSE
3389 elif "Command not found:" in output:
3390 main.log.error( "Error in processing onos:app command: " +
3391 str( output ) )
3392 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003393 elif "Unsupported command:" in output:
3394 main.log.error( "Incorrect command given to 'app': " +
3395 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003396 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003397 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003398 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003399 return main.TRUE
3400 except TypeError:
3401 main.log.exception( self.name + ": Object not as expected" )
3402 return main.ERROR
3403 except pexpect.EOF:
3404 main.log.error( self.name + ": EOF exception found" )
3405 main.log.error( self.name + ": " + self.handle.before )
3406 main.cleanup()
3407 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003408 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003409 main.log.exception( self.name + ": Uncaught exception!" )
3410 main.cleanup()
3411 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003412
Jon Hallbd16b922015-03-26 17:53:15 -07003413 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003414 """
3415 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003416 appName is the hierarchical app name, not the feature name
3417 If check is True, method will check the status of the app after the
3418 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003419 Returns main.TRUE if the command was successfully sent
3420 main.FALSE if the cli responded with an error or given
3421 incorrect input
3422 """
3423 try:
3424 if not isinstance( appName, types.StringType ):
3425 main.log.error( self.name + ".activateApp(): appName must be" +
3426 " a string" )
3427 return main.FALSE
3428 status = self.appStatus( appName )
3429 if status == "INSTALLED":
3430 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003431 if check and response == main.TRUE:
3432 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003433 status = self.appStatus( appName )
3434 if status == "ACTIVE":
3435 return main.TRUE
3436 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003437 main.log.debug( "The state of application " +
3438 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003439 time.sleep( 1 )
3440 return main.FALSE
3441 else: # not 'check' or command didn't succeed
3442 return response
Jon Hall146f1522015-03-24 15:33:24 -07003443 elif status == "ACTIVE":
3444 return main.TRUE
3445 elif status == "UNINSTALLED":
3446 main.log.error( self.name + ": Tried to activate the " +
3447 "application '" + appName + "' which is not " +
3448 "installed." )
3449 else:
3450 main.log.error( "Unexpected return value from appStatus: " +
3451 str( status ) )
3452 return main.ERROR
3453 except TypeError:
3454 main.log.exception( self.name + ": Object not as expected" )
3455 return main.ERROR
3456 except pexpect.EOF:
3457 main.log.error( self.name + ": EOF exception found" )
3458 main.log.error( self.name + ": " + self.handle.before )
3459 main.cleanup()
3460 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003461 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003462 main.log.exception( self.name + ": Uncaught exception!" )
3463 main.cleanup()
3464 main.exit()
3465
Jon Hallbd16b922015-03-26 17:53:15 -07003466 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003467 """
3468 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003469 appName is the hierarchical app name, not the feature name
3470 If check is True, method will check the status of the app after the
3471 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003472 Returns main.TRUE if the command was successfully sent
3473 main.FALSE if the cli responded with an error or given
3474 incorrect input
3475 """
3476 try:
3477 if not isinstance( appName, types.StringType ):
3478 main.log.error( self.name + ".deactivateApp(): appName must " +
3479 "be a string" )
3480 return main.FALSE
3481 status = self.appStatus( appName )
3482 if status == "INSTALLED":
3483 return main.TRUE
3484 elif status == "ACTIVE":
3485 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003486 if check and response == main.TRUE:
3487 for i in range(10): # try 10 times then give up
3488 status = self.appStatus( appName )
3489 if status == "INSTALLED":
3490 return main.TRUE
3491 else:
3492 time.sleep( 1 )
3493 return main.FALSE
3494 else: # not check or command didn't succeed
3495 return response
Jon Hall146f1522015-03-24 15:33:24 -07003496 elif status == "UNINSTALLED":
3497 main.log.warn( self.name + ": Tried to deactivate the " +
3498 "application '" + appName + "' which is not " +
3499 "installed." )
3500 return main.TRUE
3501 else:
3502 main.log.error( "Unexpected return value from appStatus: " +
3503 str( status ) )
3504 return main.ERROR
3505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
3507 return main.ERROR
3508 except pexpect.EOF:
3509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
3511 main.cleanup()
3512 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003513 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003514 main.log.exception( self.name + ": Uncaught exception!" )
3515 main.cleanup()
3516 main.exit()
3517
Jon Hallbd16b922015-03-26 17:53:15 -07003518 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003519 """
3520 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003521 appName is the hierarchical app name, not the feature name
3522 If check is True, method will check the status of the app after the
3523 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003524 Returns main.TRUE if the command was successfully sent
3525 main.FALSE if the cli responded with an error or given
3526 incorrect input
3527 """
3528 # TODO: check with Thomas about the state machine for apps
3529 try:
3530 if not isinstance( appName, types.StringType ):
3531 main.log.error( self.name + ".uninstallApp(): appName must " +
3532 "be a string" )
3533 return main.FALSE
3534 status = self.appStatus( appName )
3535 if status == "INSTALLED":
3536 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003537 if check and response == main.TRUE:
3538 for i in range(10): # try 10 times then give up
3539 status = self.appStatus( appName )
3540 if status == "UNINSTALLED":
3541 return main.TRUE
3542 else:
3543 time.sleep( 1 )
3544 return main.FALSE
3545 else: # not check or command didn't succeed
3546 return response
Jon Hall146f1522015-03-24 15:33:24 -07003547 elif status == "ACTIVE":
3548 main.log.warn( self.name + ": Tried to uninstall the " +
3549 "application '" + appName + "' which is " +
3550 "currently active." )
3551 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003552 if check and response == main.TRUE:
3553 for i in range(10): # try 10 times then give up
3554 status = self.appStatus( appName )
3555 if status == "UNINSTALLED":
3556 return main.TRUE
3557 else:
3558 time.sleep( 1 )
3559 return main.FALSE
3560 else: # not check or command didn't succeed
3561 return response
Jon Hall146f1522015-03-24 15:33:24 -07003562 elif status == "UNINSTALLED":
3563 return main.TRUE
3564 else:
3565 main.log.error( "Unexpected return value from appStatus: " +
3566 str( status ) )
3567 return main.ERROR
3568 except TypeError:
3569 main.log.exception( self.name + ": Object not as expected" )
3570 return main.ERROR
3571 except pexpect.EOF:
3572 main.log.error( self.name + ": EOF exception found" )
3573 main.log.error( self.name + ": " + self.handle.before )
3574 main.cleanup()
3575 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003576 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003577 main.log.exception( self.name + ": Uncaught exception!" )
3578 main.cleanup()
3579 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003580
3581 def appIDs( self, jsonFormat=True ):
3582 """
3583 Show the mappings between app id and app names given by the 'app-ids'
3584 cli command
3585 """
3586 try:
3587 cmdStr = "app-ids"
3588 if jsonFormat:
3589 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003590 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003591 assert "Command not found:" not in output, output
3592 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003593 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003594 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003595 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003596 return None
3597 except TypeError:
3598 main.log.exception( self.name + ": Object not as expected" )
3599 return None
3600 except pexpect.EOF:
3601 main.log.error( self.name + ": EOF exception found" )
3602 main.log.error( self.name + ": " + self.handle.before )
3603 main.cleanup()
3604 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003605 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003606 main.log.exception( self.name + ": Uncaught exception!" )
3607 main.cleanup()
3608 main.exit()
3609
3610 def appToIDCheck( self ):
3611 """
3612 This method will check that each application's ID listed in 'apps' is
3613 the same as the ID listed in 'app-ids'. The check will also check that
3614 there are no duplicate IDs issued. Note that an app ID should be
3615 a globaly unique numerical identifier for app/app-like features. Once
3616 an ID is registered, the ID is never freed up so that if an app is
3617 reinstalled it will have the same ID.
3618
3619 Returns: main.TRUE if the check passes and
3620 main.FALSE if the check fails or
3621 main.ERROR if there is some error in processing the test
3622 """
3623 try:
Jon Hall390696c2015-05-05 17:13:41 -07003624 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003625 rawJson = self.appIDs( jsonFormat=True )
3626 if rawJson:
3627 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003628 else:
Jon Hallc6793552016-01-19 14:18:37 -08003629 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003630 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003631 rawJson = self.apps( jsonFormat=True )
3632 if rawJson:
3633 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003634 else:
Jon Hallc6793552016-01-19 14:18:37 -08003635 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003636 bail = True
3637 if bail:
3638 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003639 result = main.TRUE
3640 for app in apps:
3641 appID = app.get( 'id' )
3642 if appID is None:
3643 main.log.error( "Error parsing app: " + str( app ) )
3644 result = main.FALSE
3645 appName = app.get( 'name' )
3646 if appName is None:
3647 main.log.error( "Error parsing app: " + str( app ) )
3648 result = main.FALSE
3649 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003650 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003651 # main.log.debug( "Comparing " + str( app ) + " to " +
3652 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003653 if not current: # if ids doesn't have this id
3654 result = main.FALSE
3655 main.log.error( "'app-ids' does not have the ID for " +
3656 str( appName ) + " that apps does." )
3657 elif len( current ) > 1:
3658 # there is more than one app with this ID
3659 result = main.FALSE
3660 # We will log this later in the method
3661 elif not current[0][ 'name' ] == appName:
3662 currentName = current[0][ 'name' ]
3663 result = main.FALSE
3664 main.log.error( "'app-ids' has " + str( currentName ) +
3665 " registered under id:" + str( appID ) +
3666 " but 'apps' has " + str( appName ) )
3667 else:
3668 pass # id and name match!
3669 # now make sure that app-ids has no duplicates
3670 idsList = []
3671 namesList = []
3672 for item in ids:
3673 idsList.append( item[ 'id' ] )
3674 namesList.append( item[ 'name' ] )
3675 if len( idsList ) != len( set( idsList ) ) or\
3676 len( namesList ) != len( set( namesList ) ):
3677 main.log.error( "'app-ids' has some duplicate entries: \n"
3678 + json.dumps( ids,
3679 sort_keys=True,
3680 indent=4,
3681 separators=( ',', ': ' ) ) )
3682 result = main.FALSE
3683 return result
Jon Hallc6793552016-01-19 14:18:37 -08003684 except ( TypeError, ValueError ):
3685 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003686 return main.ERROR
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
3690 main.cleanup()
3691 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003692 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003693 main.log.exception( self.name + ": Uncaught exception!" )
3694 main.cleanup()
3695 main.exit()
3696
Jon Hallfb760a02015-04-13 15:35:03 -07003697 def getCfg( self, component=None, propName=None, short=False,
3698 jsonFormat=True ):
3699 """
3700 Get configuration settings from onos cli
3701 Optional arguments:
3702 component - Optionally only list configurations for a specific
3703 component. If None, all components with configurations
3704 are displayed. Case Sensitive string.
3705 propName - If component is specified, propName option will show
3706 only this specific configuration from that component.
3707 Case Sensitive string.
3708 jsonFormat - Returns output as json. Note that this will override
3709 the short option
3710 short - Short, less verbose, version of configurations.
3711 This is overridden by the json option
3712 returns:
3713 Output from cli as a string or None on error
3714 """
3715 try:
3716 baseStr = "cfg"
3717 cmdStr = " get"
3718 componentStr = ""
3719 if component:
3720 componentStr += " " + component
3721 if propName:
3722 componentStr += " " + propName
3723 if jsonFormat:
3724 baseStr += " -j"
3725 elif short:
3726 baseStr += " -s"
3727 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003728 assert "Command not found:" not in output, output
3729 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003730 return output
3731 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003732 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003733 return None
3734 except TypeError:
3735 main.log.exception( self.name + ": Object not as expected" )
3736 return None
3737 except pexpect.EOF:
3738 main.log.error( self.name + ": EOF exception found" )
3739 main.log.error( self.name + ": " + self.handle.before )
3740 main.cleanup()
3741 main.exit()
3742 except Exception:
3743 main.log.exception( self.name + ": Uncaught exception!" )
3744 main.cleanup()
3745 main.exit()
3746
3747 def setCfg( self, component, propName, value=None, check=True ):
3748 """
3749 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003750 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003751 component - The case sensitive name of the component whose
3752 property is to be set
3753 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003754 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003755 value - The value to set the property to. If None, will unset the
3756 property and revert it to it's default value(if applicable)
3757 check - Boolean, Check whether the option was successfully set this
3758 only applies when a value is given.
3759 returns:
3760 main.TRUE on success or main.FALSE on failure. If check is False,
3761 will return main.TRUE unless there is an error
3762 """
3763 try:
3764 baseStr = "cfg"
3765 cmdStr = " set " + str( component ) + " " + str( propName )
3766 if value is not None:
3767 cmdStr += " " + str( value )
3768 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003769 assert "Command not found:" not in output, output
3770 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003771 if value and check:
3772 results = self.getCfg( component=str( component ),
3773 propName=str( propName ),
3774 jsonFormat=True )
3775 # Check if current value is what we just set
3776 try:
3777 jsonOutput = json.loads( results )
3778 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003779 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003780 main.log.exception( "Error parsing cfg output" )
3781 main.log.error( "output:" + repr( results ) )
3782 return main.FALSE
3783 if current == str( value ):
3784 return main.TRUE
3785 return main.FALSE
3786 return main.TRUE
3787 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003788 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003789 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003790 except ( TypeError, ValueError ):
3791 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003792 return main.FALSE
3793 except pexpect.EOF:
3794 main.log.error( self.name + ": EOF exception found" )
3795 main.log.error( self.name + ": " + self.handle.before )
3796 main.cleanup()
3797 main.exit()
3798 except Exception:
3799 main.log.exception( self.name + ": Uncaught exception!" )
3800 main.cleanup()
3801 main.exit()
3802
Jon Hall390696c2015-05-05 17:13:41 -07003803 def setTestAdd( self, setName, values ):
3804 """
3805 CLI command to add elements to a distributed set.
3806 Arguments:
3807 setName - The name of the set to add to.
3808 values - The value(s) to add to the set, space seperated.
3809 Example usages:
3810 setTestAdd( "set1", "a b c" )
3811 setTestAdd( "set2", "1" )
3812 returns:
3813 main.TRUE on success OR
3814 main.FALSE if elements were already in the set OR
3815 main.ERROR on error
3816 """
3817 try:
3818 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3819 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003820 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003821 try:
3822 # TODO: Maybe make this less hardcoded
3823 # ConsistentMap Exceptions
3824 assert "org.onosproject.store.service" not in output
3825 # Node not leader
3826 assert "java.lang.IllegalStateException" not in output
3827 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003828 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003829 "command: " + str( output ) )
3830 retryTime = 30 # Conservative time, given by Madan
3831 main.log.info( "Waiting " + str( retryTime ) +
3832 "seconds before retrying." )
3833 time.sleep( retryTime ) # Due to change in mastership
3834 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003835 assert "Error executing command" not in output
3836 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3837 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3838 main.log.info( self.name + ": " + output )
3839 if re.search( positiveMatch, output):
3840 return main.TRUE
3841 elif re.search( negativeMatch, output):
3842 return main.FALSE
3843 else:
3844 main.log.error( self.name + ": setTestAdd did not" +
3845 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003846 main.log.debug( self.name + " actual: " + repr( output ) )
3847 return main.ERROR
3848 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003849 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003850 return main.ERROR
3851 except TypeError:
3852 main.log.exception( self.name + ": Object not as expected" )
3853 return main.ERROR
3854 except pexpect.EOF:
3855 main.log.error( self.name + ": EOF exception found" )
3856 main.log.error( self.name + ": " + self.handle.before )
3857 main.cleanup()
3858 main.exit()
3859 except Exception:
3860 main.log.exception( self.name + ": Uncaught exception!" )
3861 main.cleanup()
3862 main.exit()
3863
3864 def setTestRemove( self, setName, values, clear=False, retain=False ):
3865 """
3866 CLI command to remove elements from a distributed set.
3867 Required arguments:
3868 setName - The name of the set to remove from.
3869 values - The value(s) to remove from the set, space seperated.
3870 Optional arguments:
3871 clear - Clear all elements from the set
3872 retain - Retain only the given values. (intersection of the
3873 original set and the given set)
3874 returns:
3875 main.TRUE on success OR
3876 main.FALSE if the set was not changed OR
3877 main.ERROR on error
3878 """
3879 try:
3880 cmdStr = "set-test-remove "
3881 if clear:
3882 cmdStr += "-c " + str( setName )
3883 elif retain:
3884 cmdStr += "-r " + str( setName ) + " " + str( values )
3885 else:
3886 cmdStr += str( setName ) + " " + str( values )
3887 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003888 try:
3889 # TODO: Maybe make this less hardcoded
3890 # ConsistentMap Exceptions
3891 assert "org.onosproject.store.service" not in output
3892 # Node not leader
3893 assert "java.lang.IllegalStateException" not in output
3894 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003895 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003896 "command: " + str( output ) )
3897 retryTime = 30 # Conservative time, given by Madan
3898 main.log.info( "Waiting " + str( retryTime ) +
3899 "seconds before retrying." )
3900 time.sleep( retryTime ) # Due to change in mastership
3901 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003902 assert "Command not found:" not in output, output
3903 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003904 main.log.info( self.name + ": " + output )
3905 if clear:
3906 pattern = "Set " + str( setName ) + " cleared"
3907 if re.search( pattern, output ):
3908 return main.TRUE
3909 elif retain:
3910 positivePattern = str( setName ) + " was pruned to contain " +\
3911 "only elements of set \[(.*)\]"
3912 negativePattern = str( setName ) + " was not changed by " +\
3913 "retaining only elements of the set " +\
3914 "\[(.*)\]"
3915 if re.search( positivePattern, output ):
3916 return main.TRUE
3917 elif re.search( negativePattern, output ):
3918 return main.FALSE
3919 else:
3920 positivePattern = "\[(.*)\] was removed from the set " +\
3921 str( setName )
3922 if ( len( values.split() ) == 1 ):
3923 negativePattern = "\[(.*)\] was not in set " +\
3924 str( setName )
3925 else:
3926 negativePattern = "No element of \[(.*)\] was in set " +\
3927 str( setName )
3928 if re.search( positivePattern, output ):
3929 return main.TRUE
3930 elif re.search( negativePattern, output ):
3931 return main.FALSE
3932 main.log.error( self.name + ": setTestRemove did not" +
3933 " match expected output" )
3934 main.log.debug( self.name + " expected: " + pattern )
3935 main.log.debug( self.name + " actual: " + repr( output ) )
3936 return main.ERROR
3937 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003938 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003939 return main.ERROR
3940 except TypeError:
3941 main.log.exception( self.name + ": Object not as expected" )
3942 return main.ERROR
3943 except pexpect.EOF:
3944 main.log.error( self.name + ": EOF exception found" )
3945 main.log.error( self.name + ": " + self.handle.before )
3946 main.cleanup()
3947 main.exit()
3948 except Exception:
3949 main.log.exception( self.name + ": Uncaught exception!" )
3950 main.cleanup()
3951 main.exit()
3952
3953 def setTestGet( self, setName, values="" ):
3954 """
3955 CLI command to get the elements in a distributed set.
3956 Required arguments:
3957 setName - The name of the set to remove from.
3958 Optional arguments:
3959 values - The value(s) to check if in the set, space seperated.
3960 returns:
3961 main.ERROR on error OR
3962 A list of elements in the set if no optional arguments are
3963 supplied OR
3964 A tuple containing the list then:
3965 main.FALSE if the given values are not in the set OR
3966 main.TRUE if the given values are in the set OR
3967 """
3968 try:
3969 values = str( values ).strip()
3970 setName = str( setName ).strip()
3971 length = len( values.split() )
3972 containsCheck = None
3973 # Patterns to match
3974 setPattern = "\[(.*)\]"
3975 pattern = "Items in set " + setName + ":\n" + setPattern
3976 containsTrue = "Set " + setName + " contains the value " + values
3977 containsFalse = "Set " + setName + " did not contain the value " +\
3978 values
3979 containsAllTrue = "Set " + setName + " contains the the subset " +\
3980 setPattern
3981 containsAllFalse = "Set " + setName + " did not contain the the" +\
3982 " subset " + setPattern
3983
3984 cmdStr = "set-test-get "
3985 cmdStr += setName + " " + values
3986 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003987 try:
3988 # TODO: Maybe make this less hardcoded
3989 # ConsistentMap Exceptions
3990 assert "org.onosproject.store.service" not in output
3991 # Node not leader
3992 assert "java.lang.IllegalStateException" not in output
3993 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003994 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003995 "command: " + str( output ) )
3996 retryTime = 30 # Conservative time, given by Madan
3997 main.log.info( "Waiting " + str( retryTime ) +
3998 "seconds before retrying." )
3999 time.sleep( retryTime ) # Due to change in mastership
4000 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004001 assert "Command not found:" not in output, output
4002 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004003 main.log.info( self.name + ": " + output )
4004
4005 if length == 0:
4006 match = re.search( pattern, output )
4007 else: # if given values
4008 if length == 1: # Contains output
4009 patternTrue = pattern + "\n" + containsTrue
4010 patternFalse = pattern + "\n" + containsFalse
4011 else: # ContainsAll output
4012 patternTrue = pattern + "\n" + containsAllTrue
4013 patternFalse = pattern + "\n" + containsAllFalse
4014 matchTrue = re.search( patternTrue, output )
4015 matchFalse = re.search( patternFalse, output )
4016 if matchTrue:
4017 containsCheck = main.TRUE
4018 match = matchTrue
4019 elif matchFalse:
4020 containsCheck = main.FALSE
4021 match = matchFalse
4022 else:
4023 main.log.error( self.name + " setTestGet did not match " +\
4024 "expected output" )
4025 main.log.debug( self.name + " expected: " + pattern )
4026 main.log.debug( self.name + " actual: " + repr( output ) )
4027 match = None
4028 if match:
4029 setMatch = match.group( 1 )
4030 if setMatch == '':
4031 setList = []
4032 else:
4033 setList = setMatch.split( ", " )
4034 if length > 0:
4035 return ( setList, containsCheck )
4036 else:
4037 return setList
4038 else: # no match
4039 main.log.error( self.name + ": setTestGet did not" +
4040 " match expected output" )
4041 main.log.debug( self.name + " expected: " + pattern )
4042 main.log.debug( self.name + " actual: " + repr( output ) )
4043 return main.ERROR
4044 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004045 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004046 return main.ERROR
4047 except TypeError:
4048 main.log.exception( self.name + ": Object not as expected" )
4049 return main.ERROR
4050 except pexpect.EOF:
4051 main.log.error( self.name + ": EOF exception found" )
4052 main.log.error( self.name + ": " + self.handle.before )
4053 main.cleanup()
4054 main.exit()
4055 except Exception:
4056 main.log.exception( self.name + ": Uncaught exception!" )
4057 main.cleanup()
4058 main.exit()
4059
4060 def setTestSize( self, setName ):
4061 """
4062 CLI command to get the elements in a distributed set.
4063 Required arguments:
4064 setName - The name of the set to remove from.
4065 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004066 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004067 None on error
4068 """
4069 try:
4070 # TODO: Should this check against the number of elements returned
4071 # and then return true/false based on that?
4072 setName = str( setName ).strip()
4073 # Patterns to match
4074 setPattern = "\[(.*)\]"
4075 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4076 setPattern
4077 cmdStr = "set-test-get -s "
4078 cmdStr += setName
4079 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004080 try:
4081 # TODO: Maybe make this less hardcoded
4082 # ConsistentMap Exceptions
4083 assert "org.onosproject.store.service" not in output
4084 # Node not leader
4085 assert "java.lang.IllegalStateException" not in output
4086 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004087 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004088 "command: " + str( output ) )
4089 retryTime = 30 # Conservative time, given by Madan
4090 main.log.info( "Waiting " + str( retryTime ) +
4091 "seconds before retrying." )
4092 time.sleep( retryTime ) # Due to change in mastership
4093 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004094 assert "Command not found:" not in output, output
4095 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004096 main.log.info( self.name + ": " + output )
4097 match = re.search( pattern, output )
4098 if match:
4099 setSize = int( match.group( 1 ) )
4100 setMatch = match.group( 2 )
4101 if len( setMatch.split() ) == setSize:
4102 main.log.info( "The size returned by " + self.name +
4103 " matches the number of elements in " +
4104 "the returned set" )
4105 else:
4106 main.log.error( "The size returned by " + self.name +
4107 " does not match the number of " +
4108 "elements in the returned set." )
4109 return setSize
4110 else: # no match
4111 main.log.error( self.name + ": setTestGet did not" +
4112 " match expected output" )
4113 main.log.debug( self.name + " expected: " + pattern )
4114 main.log.debug( self.name + " actual: " + repr( output ) )
4115 return None
4116 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004117 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004118 return None
Jon Hall390696c2015-05-05 17:13:41 -07004119 except TypeError:
4120 main.log.exception( self.name + ": Object not as expected" )
4121 return None
4122 except pexpect.EOF:
4123 main.log.error( self.name + ": EOF exception found" )
4124 main.log.error( self.name + ": " + self.handle.before )
4125 main.cleanup()
4126 main.exit()
4127 except Exception:
4128 main.log.exception( self.name + ": Uncaught exception!" )
4129 main.cleanup()
4130 main.exit()
4131
Jon Hall80daded2015-05-27 16:07:00 -07004132 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004133 """
4134 Command to list the various counters in the system.
4135 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004136 if jsonFormat, a string of the json object returned by the cli
4137 command
4138 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004139 None on error
4140 """
Jon Hall390696c2015-05-05 17:13:41 -07004141 try:
4142 counters = {}
4143 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004144 if jsonFormat:
4145 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004146 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004147 assert "Command not found:" not in output, output
4148 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004149 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004150 return output
Jon Hall390696c2015-05-05 17:13:41 -07004151 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004152 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004153 return None
Jon Hall390696c2015-05-05 17:13:41 -07004154 except TypeError:
4155 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004156 return None
Jon Hall390696c2015-05-05 17:13:41 -07004157 except pexpect.EOF:
4158 main.log.error( self.name + ": EOF exception found" )
4159 main.log.error( self.name + ": " + self.handle.before )
4160 main.cleanup()
4161 main.exit()
4162 except Exception:
4163 main.log.exception( self.name + ": Uncaught exception!" )
4164 main.cleanup()
4165 main.exit()
4166
Jon Hall935db192016-04-19 00:22:04 -07004167 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004168 """
Jon Halle1a3b752015-07-22 13:02:46 -07004169 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004170 Required arguments:
4171 counter - The name of the counter to increment.
4172 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004173 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004174 returns:
4175 integer value of the counter or
4176 None on Error
4177 """
4178 try:
4179 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004180 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004181 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004182 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004183 if delta != 1:
4184 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004185 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004186 try:
4187 # TODO: Maybe make this less hardcoded
4188 # ConsistentMap Exceptions
4189 assert "org.onosproject.store.service" not in output
4190 # Node not leader
4191 assert "java.lang.IllegalStateException" not in output
4192 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004193 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004194 "command: " + str( output ) )
4195 retryTime = 30 # Conservative time, given by Madan
4196 main.log.info( "Waiting " + str( retryTime ) +
4197 "seconds before retrying." )
4198 time.sleep( retryTime ) # Due to change in mastership
4199 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004200 assert "Command not found:" not in output, output
4201 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004202 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004203 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004204 match = re.search( pattern, output )
4205 if match:
4206 return int( match.group( 1 ) )
4207 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004208 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004209 " match expected output." )
4210 main.log.debug( self.name + " expected: " + pattern )
4211 main.log.debug( self.name + " actual: " + repr( output ) )
4212 return None
4213 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004214 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004215 return None
4216 except TypeError:
4217 main.log.exception( self.name + ": Object not as expected" )
4218 return None
4219 except pexpect.EOF:
4220 main.log.error( self.name + ": EOF exception found" )
4221 main.log.error( self.name + ": " + self.handle.before )
4222 main.cleanup()
4223 main.exit()
4224 except Exception:
4225 main.log.exception( self.name + ": Uncaught exception!" )
4226 main.cleanup()
4227 main.exit()
4228
Jon Hall935db192016-04-19 00:22:04 -07004229 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004230 """
4231 CLI command to get a distributed counter then add a delta to it.
4232 Required arguments:
4233 counter - The name of the counter to increment.
4234 Optional arguments:
4235 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004236 returns:
4237 integer value of the counter or
4238 None on Error
4239 """
4240 try:
4241 counter = str( counter )
4242 delta = int( delta )
4243 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004244 cmdStr += counter
4245 if delta != 1:
4246 cmdStr += " " + str( delta )
4247 output = self.sendline( cmdStr )
4248 try:
4249 # TODO: Maybe make this less hardcoded
4250 # ConsistentMap Exceptions
4251 assert "org.onosproject.store.service" not in output
4252 # Node not leader
4253 assert "java.lang.IllegalStateException" not in output
4254 except AssertionError:
4255 main.log.error( "Error in processing '" + cmdStr + "' " +
4256 "command: " + str( output ) )
4257 retryTime = 30 # Conservative time, given by Madan
4258 main.log.info( "Waiting " + str( retryTime ) +
4259 "seconds before retrying." )
4260 time.sleep( retryTime ) # Due to change in mastership
4261 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004262 assert "Command not found:" not in output, output
4263 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004264 main.log.info( self.name + ": " + output )
4265 pattern = counter + " was updated to (-?\d+)"
4266 match = re.search( pattern, output )
4267 if match:
4268 return int( match.group( 1 ) )
4269 else:
4270 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4271 " match expected output." )
4272 main.log.debug( self.name + " expected: " + pattern )
4273 main.log.debug( self.name + " actual: " + repr( output ) )
4274 return None
4275 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004276 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004277 return None
4278 except TypeError:
4279 main.log.exception( self.name + ": Object not as expected" )
4280 return None
4281 except pexpect.EOF:
4282 main.log.error( self.name + ": EOF exception found" )
4283 main.log.error( self.name + ": " + self.handle.before )
4284 main.cleanup()
4285 main.exit()
4286 except Exception:
4287 main.log.exception( self.name + ": Uncaught exception!" )
4288 main.cleanup()
4289 main.exit()
4290
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004291 def summary( self, jsonFormat=True ):
4292 """
4293 Description: Execute summary command in onos
4294 Returns: json object ( summary -j ), returns main.FALSE if there is
4295 no output
4296
4297 """
4298 try:
4299 cmdStr = "summary"
4300 if jsonFormat:
4301 cmdStr += " -j"
4302 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004303 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004304 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004305 if not handle:
4306 main.log.error( self.name + ": There is no output in " +
4307 "summary command" )
4308 return main.FALSE
4309 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004310 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004311 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004312 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004313 except TypeError:
4314 main.log.exception( self.name + ": Object not as expected" )
4315 return None
4316 except pexpect.EOF:
4317 main.log.error( self.name + ": EOF exception found" )
4318 main.log.error( self.name + ": " + self.handle.before )
4319 main.cleanup()
4320 main.exit()
4321 except Exception:
4322 main.log.exception( self.name + ": Uncaught exception!" )
4323 main.cleanup()
4324 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004325
Jon Hall935db192016-04-19 00:22:04 -07004326 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004327 """
4328 CLI command to get the value of a key in a consistent map using
4329 transactions. This a test function and can only get keys from the
4330 test map hard coded into the cli command
4331 Required arguments:
4332 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004333 returns:
4334 The string value of the key or
4335 None on Error
4336 """
4337 try:
4338 keyName = str( keyName )
4339 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004340 cmdStr += keyName
4341 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004342 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004343 try:
4344 # TODO: Maybe make this less hardcoded
4345 # ConsistentMap Exceptions
4346 assert "org.onosproject.store.service" not in output
4347 # Node not leader
4348 assert "java.lang.IllegalStateException" not in output
4349 except AssertionError:
4350 main.log.error( "Error in processing '" + cmdStr + "' " +
4351 "command: " + str( output ) )
4352 return None
4353 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4354 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004355 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004356 return None
4357 else:
4358 match = re.search( pattern, output )
4359 if match:
4360 return match.groupdict()[ 'value' ]
4361 else:
4362 main.log.error( self.name + ": transactionlMapGet did not" +
4363 " match expected output." )
4364 main.log.debug( self.name + " expected: " + pattern )
4365 main.log.debug( self.name + " actual: " + repr( output ) )
4366 return None
Jon Hallc6793552016-01-19 14:18:37 -08004367 except AssertionError:
4368 main.log.exception( "" )
4369 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004370 except TypeError:
4371 main.log.exception( self.name + ": Object not as expected" )
4372 return None
4373 except pexpect.EOF:
4374 main.log.error( self.name + ": EOF exception found" )
4375 main.log.error( self.name + ": " + self.handle.before )
4376 main.cleanup()
4377 main.exit()
4378 except Exception:
4379 main.log.exception( self.name + ": Uncaught exception!" )
4380 main.cleanup()
4381 main.exit()
4382
Jon Hall935db192016-04-19 00:22:04 -07004383 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004384 """
4385 CLI command to put a value into 'numKeys' number of keys in a
4386 consistent map using transactions. This a test function and can only
4387 put into keys named 'Key#' of the test map hard coded into the cli command
4388 Required arguments:
4389 numKeys - Number of keys to add the value to
4390 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004391 returns:
4392 A dictionary whose keys are the name of the keys put into the map
4393 and the values of the keys are dictionaries whose key-values are
4394 'value': value put into map and optionaly
4395 'oldValue': Previous value in the key or
4396 None on Error
4397
4398 Example output
4399 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4400 'Key2': {'value': 'Testing'} }
4401 """
4402 try:
4403 numKeys = str( numKeys )
4404 value = str( value )
4405 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004406 cmdStr += numKeys + " " + value
4407 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004408 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004409 try:
4410 # TODO: Maybe make this less hardcoded
4411 # ConsistentMap Exceptions
4412 assert "org.onosproject.store.service" not in output
4413 # Node not leader
4414 assert "java.lang.IllegalStateException" not in output
4415 except AssertionError:
4416 main.log.error( "Error in processing '" + cmdStr + "' " +
4417 "command: " + str( output ) )
4418 return None
4419 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4420 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4421 results = {}
4422 for line in output.splitlines():
4423 new = re.search( newPattern, line )
4424 updated = re.search( updatedPattern, line )
4425 if new:
4426 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4427 elif updated:
4428 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004429 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004430 else:
4431 main.log.error( self.name + ": transactionlMapGet did not" +
4432 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004433 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4434 newPattern,
4435 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004436 main.log.debug( self.name + " actual: " + repr( output ) )
4437 return results
Jon Hallc6793552016-01-19 14:18:37 -08004438 except AssertionError:
4439 main.log.exception( "" )
4440 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return None
4444 except pexpect.EOF:
4445 main.log.error( self.name + ": EOF exception found" )
4446 main.log.error( self.name + ": " + self.handle.before )
4447 main.cleanup()
4448 main.exit()
4449 except Exception:
4450 main.log.exception( self.name + ": Uncaught exception!" )
4451 main.cleanup()
4452 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004453
acsmarsdaea66c2015-09-03 11:44:06 -07004454 def maps( self, jsonFormat=True ):
4455 """
4456 Description: Returns result of onos:maps
4457 Optional:
4458 * jsonFormat: enable json formatting of output
4459 """
4460 try:
4461 cmdStr = "maps"
4462 if jsonFormat:
4463 cmdStr += " -j"
4464 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004465 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004466 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004467 except AssertionError:
4468 main.log.exception( "" )
4469 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return None
4473 except pexpect.EOF:
4474 main.log.error( self.name + ": EOF exception found" )
4475 main.log.error( self.name + ": " + self.handle.before )
4476 main.cleanup()
4477 main.exit()
4478 except Exception:
4479 main.log.exception( self.name + ": Uncaught exception!" )
4480 main.cleanup()
4481 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004482
4483 def getSwController( self, uri, jsonFormat=True ):
4484 """
4485 Descrition: Gets the controller information from the device
4486 """
4487 try:
4488 cmd = "device-controllers "
4489 if jsonFormat:
4490 cmd += "-j "
4491 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004492 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004493 return response
Jon Hallc6793552016-01-19 14:18:37 -08004494 except AssertionError:
4495 main.log.exception( "" )
4496 return None
GlennRC050596c2015-11-18 17:06:41 -08004497 except TypeError:
4498 main.log.exception( self.name + ": Object not as expected" )
4499 return None
4500 except pexpect.EOF:
4501 main.log.error( self.name + ": EOF exception found" )
4502 main.log.error( self.name + ": " + self.handle.before )
4503 main.cleanup()
4504 main.exit()
4505 except Exception:
4506 main.log.exception( self.name + ": Uncaught exception!" )
4507 main.cleanup()
4508 main.exit()
4509
4510 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4511 """
4512 Descrition: sets the controller(s) for the specified device
4513
4514 Parameters:
4515 Required: uri - String: The uri of the device(switch).
4516 ip - String or List: The ip address of the controller.
4517 This parameter can be formed in a couple of different ways.
4518 VALID:
4519 10.0.0.1 - just the ip address
4520 tcp:10.0.0.1 - the protocol and the ip address
4521 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4522 so that you can add controllers with different
4523 protocols and ports
4524 INVALID:
4525 10.0.0.1:6653 - this is not supported by ONOS
4526
4527 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4528 port - The port number.
4529 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4530
4531 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4532 """
4533 try:
4534 cmd = "device-setcontrollers"
4535
4536 if jsonFormat:
4537 cmd += " -j"
4538 cmd += " " + uri
4539 if isinstance( ip, str ):
4540 ip = [ip]
4541 for item in ip:
4542 if ":" in item:
4543 sitem = item.split( ":" )
4544 if len(sitem) == 3:
4545 cmd += " " + item
4546 elif "." in sitem[1]:
4547 cmd += " {}:{}".format(item, port)
4548 else:
4549 main.log.error( "Malformed entry: " + item )
4550 raise TypeError
4551 else:
4552 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004553 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004554 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004555 if "Error" in response:
4556 main.log.error( response )
4557 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004558 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004559 except AssertionError:
4560 main.log.exception( "" )
4561 return None
GlennRC050596c2015-11-18 17:06:41 -08004562 except TypeError:
4563 main.log.exception( self.name + ": Object not as expected" )
4564 return main.FALSE
4565 except pexpect.EOF:
4566 main.log.error( self.name + ": EOF exception found" )
4567 main.log.error( self.name + ": " + self.handle.before )
4568 main.cleanup()
4569 main.exit()
4570 except Exception:
4571 main.log.exception( self.name + ": Uncaught exception!" )
4572 main.cleanup()
4573 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004574
4575 def removeDevice( self, device ):
4576 '''
4577 Description:
4578 Remove a device from ONOS by passing the uri of the device(s).
4579 Parameters:
4580 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4581 Returns:
4582 Returns main.FALSE if an exception is thrown or an error is present
4583 in the response. Otherwise, returns main.TRUE.
4584 NOTE:
4585 If a host cannot be removed, then this function will return main.FALSE
4586 '''
4587 try:
4588 if type( device ) is str:
4589 device = list( device )
4590
4591 for d in device:
4592 time.sleep( 1 )
4593 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004594 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004595 if "Error" in response:
4596 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4597 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004598 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004599 except AssertionError:
4600 main.log.exception( "" )
4601 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004602 except TypeError:
4603 main.log.exception( self.name + ": Object not as expected" )
4604 return main.FALSE
4605 except pexpect.EOF:
4606 main.log.error( self.name + ": EOF exception found" )
4607 main.log.error( self.name + ": " + self.handle.before )
4608 main.cleanup()
4609 main.exit()
4610 except Exception:
4611 main.log.exception( self.name + ": Uncaught exception!" )
4612 main.cleanup()
4613 main.exit()
4614
4615 def removeHost( self, host ):
4616 '''
4617 Description:
4618 Remove a host from ONOS by passing the id of the host(s)
4619 Parameters:
4620 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4621 Returns:
4622 Returns main.FALSE if an exception is thrown or an error is present
4623 in the response. Otherwise, returns main.TRUE.
4624 NOTE:
4625 If a host cannot be removed, then this function will return main.FALSE
4626 '''
4627 try:
4628 if type( host ) is str:
4629 host = list( host )
4630
4631 for h in host:
4632 time.sleep( 1 )
4633 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004634 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004635 if "Error" in response:
4636 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4637 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004638 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004639 except AssertionError:
4640 main.log.exception( "" )
4641 return None
GlennRC20fc6522015-12-23 23:26:57 -08004642 except TypeError:
4643 main.log.exception( self.name + ": Object not as expected" )
4644 return main.FALSE
4645 except pexpect.EOF:
4646 main.log.error( self.name + ": EOF exception found" )
4647 main.log.error( self.name + ": " + self.handle.before )
4648 main.cleanup()
4649 main.exit()
4650 except Exception:
4651 main.log.exception( self.name + ": Uncaught exception!" )
4652 main.cleanup()
4653 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004654
Jon Hallc6793552016-01-19 14:18:37 -08004655 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004656 '''
4657 Description:
4658 Bring link down or up in the null-provider.
4659 params:
4660 begin - (string) One end of a device or switch.
4661 end - (string) the other end of the device or switch
4662 returns:
4663 main.TRUE if no exceptions were thrown and no Errors are
4664 present in the resoponse. Otherwise, returns main.FALSE
4665 '''
4666 try:
Jon Hallc6793552016-01-19 14:18:37 -08004667 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004668 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004669 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004670 if "Error" in response or "Failure" in response:
4671 main.log.error( response )
4672 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004673 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004674 except AssertionError:
4675 main.log.exception( "" )
4676 return None
GlennRCed771242016-01-13 17:02:47 -08004677 except TypeError:
4678 main.log.exception( self.name + ": Object not as expected" )
4679 return main.FALSE
4680 except pexpect.EOF:
4681 main.log.error( self.name + ": EOF exception found" )
4682 main.log.error( self.name + ": " + self.handle.before )
4683 main.cleanup()
4684 main.exit()
4685 except Exception:
4686 main.log.exception( self.name + ": Uncaught exception!" )
4687 main.cleanup()
4688 main.exit()
4689