blob: 7e5cb3c89d5262eda2f273975e8ee2b5e17597b1 [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
Jon Hallefbd9792015-03-05 16:11:36 -0800385 def log( self, cmdStr, level="" ):
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
kelvin-onlab338f5512015-02-06 10:53:16 -0800390 Available level: DEBUG, TRACE, INFO, WARN, ERROR
391 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800392 """
393 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 lvlStr = ""
395 if level:
396 lvlStr = "--level=" + level
397
kelvin-onlab9f541032015-02-04 16:19:53 -0800398 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800399 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700400 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800401 main.log.error( self.name + ": onos cli session closed. ")
402 if self.onosIp:
403 main.log.warn( "Trying to reconnect " + self.onosIp )
404 reconnectResult = self.startOnosCli( self.onosIp )
405 if reconnectResult:
406 main.log.info( self.name + ": onos cli session reconnected." )
407 else:
408 main.log.error( self.name + ": reconnection failed." )
409 main.cleanup()
410 main.exit()
411 else:
412 main.cleanup()
413 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700414 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700415 self.handle.sendline( "" )
416 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800417 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700418 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800420
kelvin-onlab9f541032015-02-04 16:19:53 -0800421 response = self.handle.before
422 if re.search( "Error", response ):
423 return main.FALSE
424 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700425 except pexpect.TIMEOUT:
426 main.log.exception( self.name + ": TIMEOUT exception found" )
427 main.cleanup()
428 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 except pexpect.EOF:
430 main.log.error( self.name + ": EOF exception found" )
431 main.log.error( self.name + ": " + self.handle.before )
432 main.cleanup()
433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800434 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800435 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400436 main.cleanup()
437 main.exit()
438
GlennRCed771242016-01-13 17:02:47 -0800439 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800440 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800441 Send a completely user specified string to
442 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400443 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800444
andrewonlaba18f6bf2014-10-13 19:31:54 -0400445 Warning: There are no sanity checking to commands
446 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800447
kelvin8ec71442015-01-15 16:57:00 -0800448 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400449 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700450 if debug:
451 # NOTE: This adds and average of .4 seconds per call
452 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
453 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800454 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800455 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800456 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800457 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800458 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
459 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700460 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700461 main.log.debug( self.name + ": Raw output" )
462 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700463
464 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800465 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800466 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700467 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700468 main.log.debug( self.name + ": ansiEscape output" )
469 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700470
kelvin-onlabfb521662015-02-27 09:52:40 -0800471 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800472 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700473 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700474 main.log.debug( self.name + ": Removed extra returns " +
475 "from output" )
476 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700477
478 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800479 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700480 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700481 main.log.debug( self.name + ": parsed and stripped output" )
482 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483
Jon Hall63604932015-02-26 17:09:50 -0800484 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700485 output = response.split( cmdStr.strip(), 1 )
486 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700487 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800490 output = output[1].strip()
491 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800492 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800493 return output
GlennRCed771242016-01-13 17:02:47 -0800494 except pexpect.TIMEOUT:
495 main.log.error( self.name + ":ONOS timeout" )
496 if debug:
497 main.log.debug( self.handle.before )
498 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700499 except IndexError:
500 main.log.exception( self.name + ": Object not as expected" )
501 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800502 except TypeError:
503 main.log.exception( self.name + ": Object not as expected" )
504 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400505 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800506 main.log.error( self.name + ": EOF exception found" )
507 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400508 main.cleanup()
509 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800510 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800511 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400512 main.cleanup()
513 main.exit()
514
kelvin8ec71442015-01-15 16:57:00 -0800515 # IMPORTANT NOTE:
516 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 # the cli command changing 'a:b' with 'aB'.
518 # Ex ) onos:topology > onosTopology
519 # onos:links > onosLinks
520 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800521
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800523 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400524 Adds a new cluster node by ID and address information.
525 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800526 * nodeId
527 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800530 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400531 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 cmdStr = "add-node " + str( nodeId ) + " " +\
533 str( ONOSIp ) + " " + str( tcpPort )
534 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800535 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800536 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800537 main.log.error( "Error in adding node" )
538 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800539 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400540 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400542 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800543 except AssertionError:
544 main.log.exception( "" )
545 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800546 except TypeError:
547 main.log.exception( self.name + ": Object not as expected" )
548 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800550 main.log.error( self.name + ": EOF exception found" )
551 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400552 main.cleanup()
553 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800554 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800555 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400556 main.cleanup()
557 main.exit()
558
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlab86dc3082014-10-13 18:18:38 -0400561 Removes a cluster by ID
562 Issues command: 'remove-node [<node-id>]'
563 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800565 """
andrewonlab86dc3082014-10-13 18:18:38 -0400566 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400567
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700569 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800570 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700571 if re.search( "Error", handle ):
572 main.log.error( "Error in removing node" )
573 main.log.error( handle )
574 return main.FALSE
575 else:
576 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800577 except AssertionError:
578 main.log.exception( "" )
579 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800580 except TypeError:
581 main.log.exception( self.name + ": Object not as expected" )
582 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800584 main.log.error( self.name + ": EOF exception found" )
585 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400586 main.cleanup()
587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800588 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800589 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400590 main.cleanup()
591 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592
Jon Hall61282e32015-03-19 11:34:11 -0700593 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800594 """
andrewonlab7c211572014-10-15 16:45:20 -0400595 List the nodes currently visible
596 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700597 Optional argument:
598 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800599 """
andrewonlab7c211572014-10-15 16:45:20 -0400600 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700601 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700602 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 cmdStr += " -j"
604 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800605 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700606 return output
Jon Hallc6793552016-01-19 14:18:37 -0800607 except AssertionError:
608 main.log.exception( "" )
609 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800610 except TypeError:
611 main.log.exception( self.name + ": Object not as expected" )
612 return None
andrewonlab7c211572014-10-15 16:45:20 -0400613 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400616 main.cleanup()
617 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800618 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800619 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400620 main.cleanup()
621 main.exit()
622
kelvin8ec71442015-01-15 16:57:00 -0800623 def topology( self ):
624 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700625 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700626 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700627 Return:
628 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800629 """
andrewonlab95ce8322014-10-13 14:12:04 -0400630 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700631 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800633 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400635 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800636 except AssertionError:
637 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800638 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400645 main.cleanup()
646 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400649 main.cleanup()
650 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800651
jenkins7ead5a82015-03-13 10:28:21 -0700652 def deviceRemove( self, deviceId ):
653 """
654 Removes particular device from storage
655
656 TODO: refactor this function
657 """
658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "device-remove " + str( deviceId )
660 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800661 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 if re.search( "Error", handle ):
663 main.log.error( "Error in removing device" )
664 main.log.error( handle )
665 return main.FALSE
666 else:
667 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
670 return None
jenkins7ead5a82015-03-13 10:28:21 -0700671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
674 except pexpect.EOF:
675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
677 main.cleanup()
678 main.exit()
679 except Exception:
680 main.log.exception( self.name + ": Uncaught exception!" )
681 main.cleanup()
682 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700683
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800685 """
Jon Hall7b02d952014-10-17 20:14:54 -0400686 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400687 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800689 """
andrewonlab86dc3082014-10-13 18:18:38 -0400690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700693 cmdStr += " -j"
694 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800695 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700696 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800697 except AssertionError:
698 main.log.exception( "" )
699 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800700 except TypeError:
701 main.log.exception( self.name + ": Object not as expected" )
702 return None
andrewonlab7c211572014-10-15 16:45:20 -0400703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800704 main.log.error( self.name + ": EOF exception found" )
705 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400706 main.cleanup()
707 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800708 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800709 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400710 main.cleanup()
711 main.exit()
712
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800714 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800715 This balances the devices across all controllers
716 by issuing command: 'onos> onos:balance-masters'
717 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800718 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800719 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700721 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800722 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 if re.search( "Error", handle ):
724 main.log.error( "Error in balancing masters" )
725 main.log.error( handle )
726 return main.FALSE
727 else:
728 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800729 except AssertionError:
730 main.log.exception( "" )
731 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800732 except TypeError:
733 main.log.exception( self.name + ": Object not as expected" )
734 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800735 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800736 main.log.error( self.name + ": EOF exception found" )
737 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800742 main.cleanup()
743 main.exit()
744
Jon Hallc6793552016-01-19 14:18:37 -0800745 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700746 """
747 Returns the output of the masters command.
748 Optional argument:
749 * jsonFormat - boolean indicating if you want output in json
750 """
751 try:
752 cmdStr = "onos:masters"
753 if jsonFormat:
754 cmdStr += " -j"
755 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800756 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700757 return output
Jon Hallc6793552016-01-19 14:18:37 -0800758 except AssertionError:
759 main.log.exception( "" )
760 return None
acsmars24950022015-07-30 18:00:43 -0700761 except TypeError:
762 main.log.exception( self.name + ": Object not as expected" )
763 return None
764 except pexpect.EOF:
765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
767 main.cleanup()
768 main.exit()
769 except Exception:
770 main.log.exception( self.name + ": Uncaught exception!" )
771 main.cleanup()
772 main.exit()
773
Jon Hallc6793552016-01-19 14:18:37 -0800774 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700775 """
776 Uses the master command to check that the devices' leadership
777 is evenly divided
778
779 Dependencies: checkMasters() and summary()
780
781 Returns main.True if the devices are balanced
782 Returns main.False if the devices are unbalanced
783 Exits on Exception
784 Returns None on TypeError
785 """
786 try:
Jon Hallc6793552016-01-19 14:18:37 -0800787 summaryOutput = self.summary()
788 totalDevices = json.loads( summaryOutput )[ "devices" ]
789 except ( TypeError, ValueError ):
790 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
791 return None
792 try:
acsmars24950022015-07-30 18:00:43 -0700793 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800794 mastersOutput = self.checkMasters()
795 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700796 first = masters[ 0 ][ "size" ]
797 for master in masters:
798 totalOwnedDevices += master[ "size" ]
799 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
800 main.log.error( "Mastership not balanced" )
801 main.log.info( "\n" + self.checkMasters( False ) )
802 return main.FALSE
803 main.log.info( "Mastership balanced between " \
804 + str( len(masters) ) + " masters" )
805 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800806 except ( TypeError, ValueError ):
807 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700808 return None
809 except pexpect.EOF:
810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
812 main.cleanup()
813 main.exit()
814 except Exception:
815 main.log.exception( self.name + ": Uncaught exception!" )
816 main.cleanup()
817 main.exit()
818
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800820 """
Jon Halle8217482014-10-17 13:49:14 -0400821 Lists all core links
822 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800824 """
Jon Halle8217482014-10-17 13:49:14 -0400825 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700826 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700828 cmdStr += " -j"
829 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800830 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700831 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800832 except AssertionError:
833 main.log.exception( "" )
834 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800835 except TypeError:
836 main.log.exception( self.name + ": Object not as expected" )
837 return None
Jon Halle8217482014-10-17 13:49:14 -0400838 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400841 main.cleanup()
842 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800843 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800844 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400845 main.cleanup()
846 main.exit()
847
kelvin-onlabd3b64892015-01-20 13:26:24 -0800848 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Halle8217482014-10-17 13:49:14 -0400850 Lists all ports
851 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Halle8217482014-10-17 13:49:14 -0400854 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700855 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700857 cmdStr += " -j"
858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800859 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700860 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800861 except AssertionError:
862 main.log.exception( "" )
863 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800864 except TypeError:
865 main.log.exception( self.name + ": Object not as expected" )
866 return None
Jon Halle8217482014-10-17 13:49:14 -0400867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400870 main.cleanup()
871 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800872 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800873 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400874 main.cleanup()
875 main.exit()
876
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800878 """
Jon Hall983a1702014-10-28 18:44:22 -0400879 Lists all devices and the controllers with roles assigned to them
880 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800882 """
andrewonlab7c211572014-10-15 16:45:20 -0400883 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 cmdStr += " -j"
887 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800888 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700889 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800890 except AssertionError:
891 main.log.exception( "" )
892 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800893 except TypeError:
894 main.log.exception( self.name + ": Object not as expected" )
895 return None
Jon Hall983a1702014-10-28 18:44:22 -0400896 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400899 main.cleanup()
900 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800901 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800902 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400903 main.cleanup()
904 main.exit()
905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800907 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800908 Given the a string containing the json representation of the "roles"
909 cli command and a partial or whole device id, returns a json object
910 containing the roles output for the first device whose id contains
911 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400912
913 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800914 A dict of the role assignments for the given device or
915 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800916 """
Jon Hall983a1702014-10-28 18:44:22 -0400917 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400919 return None
920 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 rawRoles = self.roles()
922 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800923 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800925 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400927 return device
928 return None
Jon Hallc6793552016-01-19 14:18:37 -0800929 except ( TypeError, ValueError ):
930 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800931 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400932 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800933 main.log.error( self.name + ": EOF exception found" )
934 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400935 main.cleanup()
936 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800937 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800938 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400939 main.cleanup()
940 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800941
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800943 """
Jon Hall94fd0472014-12-08 11:52:42 -0800944 Iterates through each device and checks if there is a master assigned
945 Returns: main.TRUE if each device has a master
946 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800947 """
Jon Hall94fd0472014-12-08 11:52:42 -0800948 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 rawRoles = self.roles()
950 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800951 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800953 # print device
954 if device[ 'master' ] == "none":
955 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800956 return main.FALSE
957 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800958 except ( TypeError, ValueError ):
959 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800960 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800964 main.cleanup()
965 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800966 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800967 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800968 main.cleanup()
969 main.exit()
970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400973 Returns string of paths, and the cost.
974 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800975 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400976 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
978 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800979 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800980 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800981 main.log.error( "Error in getting paths" )
982 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400983 else:
kelvin8ec71442015-01-15 16:57:00 -0800984 path = handle.split( ";" )[ 0 ]
985 cost = handle.split( ";" )[ 1 ]
986 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800987 except AssertionError:
988 main.log.exception( "" )
989 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800990 except TypeError:
991 main.log.exception( self.name + ": Object not as expected" )
992 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400993 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800994 main.log.error( self.name + ": EOF exception found" )
995 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400996 main.cleanup()
997 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800998 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800999 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001000 main.cleanup()
1001 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001002
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001004 """
Jon Hallffb386d2014-11-21 13:43:38 -08001005 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001006 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001008 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001009 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001010 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001012 cmdStr += " -j"
1013 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001014 if handle:
1015 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001016 # TODO: Maybe make this less hardcoded
1017 # ConsistentMap Exceptions
1018 assert "org.onosproject.store.service" not in handle
1019 # Node not leader
1020 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001021 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001022 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001023 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001024 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001026 except TypeError:
1027 main.log.exception( self.name + ": Object not as expected" )
1028 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.error( self.name + ": EOF exception found" )
1031 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 main.cleanup()
1033 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001034 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001035 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001036 main.cleanup()
1037 main.exit()
1038
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001040 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001041 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001042
Jon Hallefbd9792015-03-05 16:11:36 -08001043 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001044 partial mac address
1045
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001047 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 try:
kelvin8ec71442015-01-15 16:57:00 -08001049 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 return None
1051 else:
1052 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 rawHosts = self.hosts()
1054 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001055 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001056 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001057 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001058 if not host:
1059 pass
1060 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001061 return host
1062 return None
Jon Hallc6793552016-01-19 14:18:37 -08001063 except ( TypeError, ValueError ):
1064 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001065 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001067 main.log.error( self.name + ": EOF exception found" )
1068 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 main.cleanup()
1070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001072 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001073 main.cleanup()
1074 main.exit()
1075
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001077 """
1078 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001079 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001080
andrewonlab3f0a4af2014-10-17 12:25:14 -04001081 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001083 IMPORTANT:
1084 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001085 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001086 Furthermore, it assumes that value of VLAN is '-1'
1087 Description:
kelvin8ec71442015-01-15 16:57:00 -08001088 Converts mininet hosts ( h1, h2, h3... ) into
1089 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1090 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001091 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001093
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001095 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 hostHex = hex( int( host ) ).zfill( 12 )
1097 hostHex = str( hostHex ).replace( 'x', '0' )
1098 i = iter( str( hostHex ) )
1099 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1100 hostHex = hostHex + "/-1"
1101 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001102
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001104
Jon Halld4d4b372015-01-28 16:02:41 -08001105 except TypeError:
1106 main.log.exception( self.name + ": Object not as expected" )
1107 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001108 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001109 main.log.error( self.name + ": EOF exception found" )
1110 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001111 main.cleanup()
1112 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001114 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001115 main.cleanup()
1116 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001117
Jeremy Songster832f9e92016-05-05 14:30:49 -07001118 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001119 """
andrewonlabe6745342014-10-17 14:29:13 -04001120 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 * hostIdOne: ONOS host id for host1
1122 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001123 Optional:
1124 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001125 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001126 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001127 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001128 Returns:
1129 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001130 """
andrewonlabe6745342014-10-17 14:29:13 -04001131 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001132 cmdStr = "add-host-intent "
1133 if vlanId:
1134 cmdStr += "-v " + str( vlanId ) + " "
1135 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001137 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001138 if re.search( "Error", handle ):
1139 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001140 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001141 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001142 else:
1143 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001144 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1145 match = re.search('id=0x([\da-f]+),', handle)
1146 if match:
1147 return match.group()[3:-1]
1148 else:
1149 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001150 main.log.debug( "Response from ONOS was: " +
1151 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001152 return None
Jon Hallc6793552016-01-19 14:18:37 -08001153 except AssertionError:
1154 main.log.exception( "" )
1155 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001156 except TypeError:
1157 main.log.exception( self.name + ": Object not as expected" )
1158 return None
andrewonlabe6745342014-10-17 14:29:13 -04001159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001160 main.log.error( self.name + ": EOF exception found" )
1161 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001162 main.cleanup()
1163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001166 main.cleanup()
1167 main.exit()
1168
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001170 """
andrewonlab7b31d232014-10-24 13:31:47 -04001171 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 * ingressDevice: device id of ingress device
1173 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001174 Optional:
1175 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001176 Description:
1177 Adds an optical intent by specifying an ingress and egress device
1178 Returns:
1179 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001180 """
andrewonlab7b31d232014-10-24 13:31:47 -04001181 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1183 " " + str( egressDevice )
1184 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001185 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001186 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001187 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 main.log.error( "Error in adding Optical intent" )
1189 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001190 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001191 main.log.info( "Optical intent installed between " +
1192 str( ingressDevice ) + " and " +
1193 str( egressDevice ) )
1194 match = re.search('id=0x([\da-f]+),', handle)
1195 if match:
1196 return match.group()[3:-1]
1197 else:
1198 main.log.error( "Error, intent ID not found" )
1199 return None
Jon Hallc6793552016-01-19 14:18:37 -08001200 except AssertionError:
1201 main.log.exception( "" )
1202 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001203 except TypeError:
1204 main.log.exception( self.name + ": Object not as expected" )
1205 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001206 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001207 main.log.error( self.name + ": EOF exception found" )
1208 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001209 main.cleanup()
1210 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001211 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001212 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001213 main.cleanup()
1214 main.exit()
1215
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001217 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 ingressDevice,
1219 egressDevice,
1220 portIngress="",
1221 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 ethType="",
1223 ethSrc="",
1224 ethDst="",
1225 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001227 ipProto="",
1228 ipSrc="",
1229 ipDst="",
1230 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001231 tcpDst="",
1232 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001233 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001234 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 * ingressDevice: device id of ingress device
1236 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001237 Optional:
1238 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001239 * ethSrc: specify ethSrc ( i.e. src mac addr )
1240 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001241 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001243 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001244 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001245 * ipSrc: specify ip source address
1246 * ipDst: specify ip destination address
1247 * tcpSrc: specify tcp source port
1248 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001249 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001250 Description:
kelvin8ec71442015-01-15 16:57:00 -08001251 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001252 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001253 Returns:
1254 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001255
Jon Halle3f39ff2015-01-13 11:50:53 -08001256 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001257 options developers provide for point-to-point
1258 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001259 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001260 try:
kelvin8ec71442015-01-15 16:57:00 -08001261 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001262 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001264 and not ipProto and not ipSrc and not ipDst \
1265 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001266 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001267
andrewonlab289e4b72014-10-21 21:24:18 -04001268 else:
andrewonlab36af3822014-11-18 17:48:18 -05001269 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001270
andrewonlab0c0a6772014-10-22 12:31:18 -04001271 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001272 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001273 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001274 cmd += " --ethSrc " + str( ethSrc )
1275 if ethDst:
1276 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001277 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001278 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001280 cmd += " --lambda "
1281 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001282 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001283 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001284 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001285 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001286 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001287 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001288 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001289 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001290 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001291 if vlanId:
1292 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001293
kelvin8ec71442015-01-15 16:57:00 -08001294 # Check whether the user appended the port
1295 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 if "/" in ingressDevice:
1297 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001298 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001300 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001301 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001302 # Would it make sense to throw an exception and exit
1303 # the test?
1304 return None
andrewonlab36af3822014-11-18 17:48:18 -05001305
kelvin8ec71442015-01-15 16:57:00 -08001306 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 str( ingressDevice ) + "/" +\
1308 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001309
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 if "/" in egressDevice:
1311 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001312 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001314 main.log.error( "You must specify the egress port" )
1315 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001316
kelvin8ec71442015-01-15 16:57:00 -08001317 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 str( egressDevice ) + "/" +\
1319 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001320
kelvin-onlab898a6c62015-01-16 14:13:53 -08001321 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001322 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001323 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001324 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001325 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001326 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001327 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001328 # TODO: print out all the options in this message?
1329 main.log.info( "Point-to-point intent installed between " +
1330 str( ingressDevice ) + " and " +
1331 str( egressDevice ) )
1332 match = re.search('id=0x([\da-f]+),', handle)
1333 if match:
1334 return match.group()[3:-1]
1335 else:
1336 main.log.error( "Error, intent ID not found" )
1337 return None
Jon Hallc6793552016-01-19 14:18:37 -08001338 except AssertionError:
1339 main.log.exception( "" )
1340 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001341 except TypeError:
1342 main.log.exception( self.name + ": Object not as expected" )
1343 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001344 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001345 main.log.error( self.name + ": EOF exception found" )
1346 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001347 main.cleanup()
1348 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001349 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001350 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001351 main.cleanup()
1352 main.exit()
1353
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001355 self,
shahshreyac2f97072015-03-19 17:04:29 -07001356 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001358 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001360 ethType="",
1361 ethSrc="",
1362 ethDst="",
1363 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001364 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 ipProto="",
1366 ipSrc="",
1367 ipDst="",
1368 tcpSrc="",
1369 tcpDst="",
1370 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001371 setEthDst="",
1372 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001373 """
shahshreyad0c80432014-12-04 16:56:05 -08001374 Note:
shahshreya70622b12015-03-19 17:19:00 -07001375 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001376 is same. That is, all ingress devices include port numbers
1377 with a "/" or all ingress devices could specify device
1378 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001379 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001380 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001381 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001383 Optional:
1384 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001385 * ethSrc: specify ethSrc ( i.e. src mac addr )
1386 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001387 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001389 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001390 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001391 * ipSrc: specify ip source address
1392 * ipDst: specify ip destination address
1393 * tcpSrc: specify tcp source port
1394 * tcpDst: specify tcp destination port
1395 * setEthSrc: action to Rewrite Source MAC Address
1396 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001397 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001398 Description:
kelvin8ec71442015-01-15 16:57:00 -08001399 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001400 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 Returns:
1402 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001403
Jon Halle3f39ff2015-01-13 11:50:53 -08001404 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001405 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001406 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001407 """
shahshreyad0c80432014-12-04 16:56:05 -08001408 try:
kelvin8ec71442015-01-15 16:57:00 -08001409 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001410 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001412 and not ipProto and not ipSrc and not ipDst\
1413 and not tcpSrc and not tcpDst and not setEthSrc\
1414 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001415 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001416
1417 else:
1418 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001419
shahshreyad0c80432014-12-04 16:56:05 -08001420 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001421 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001422 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001423 cmd += " --ethSrc " + str( ethSrc )
1424 if ethDst:
1425 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001426 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001427 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001429 cmd += " --lambda "
1430 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001431 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001432 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001433 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001434 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001435 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001436 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001437 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001438 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001439 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001440 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001441 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001442 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001443 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001444 if vlanId:
1445 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001446
kelvin8ec71442015-01-15 16:57:00 -08001447 # Check whether the user appended the port
1448 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001449
1450 if portIngressList is None:
1451 for ingressDevice in ingressDeviceList:
1452 if "/" in ingressDevice:
1453 cmd += " " + str( ingressDevice )
1454 else:
1455 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001456 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001457 # TODO: perhaps more meaningful return
1458 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001459 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001460 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001461 for ingressDevice, portIngress in zip( ingressDeviceList,
1462 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001463 cmd += " " + \
1464 str( ingressDevice ) + "/" +\
1465 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001466 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001467 main.log.error( "Device list and port list does not " +
1468 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001469 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001470 if "/" in egressDevice:
1471 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001472 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001474 main.log.error( "You must specify " +
1475 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001476 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001477
kelvin8ec71442015-01-15 16:57:00 -08001478 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 str( egressDevice ) + "/" +\
1480 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001482 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001484 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001485 main.log.error( "Error in adding multipoint-to-singlepoint " +
1486 "intent" )
1487 return None
shahshreyad0c80432014-12-04 16:56:05 -08001488 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001489 match = re.search('id=0x([\da-f]+),', handle)
1490 if match:
1491 return match.group()[3:-1]
1492 else:
1493 main.log.error( "Error, intent ID not found" )
1494 return None
Jon Hallc6793552016-01-19 14:18:37 -08001495 except AssertionError:
1496 main.log.exception( "" )
1497 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001498 except TypeError:
1499 main.log.exception( self.name + ": Object not as expected" )
1500 return None
1501 except pexpect.EOF:
1502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
1504 main.cleanup()
1505 main.exit()
1506 except Exception:
1507 main.log.exception( self.name + ": Uncaught exception!" )
1508 main.cleanup()
1509 main.exit()
1510
1511 def addSinglepointToMultipointIntent(
1512 self,
1513 ingressDevice,
1514 egressDeviceList,
1515 portIngress="",
1516 portEgressList=None,
1517 ethType="",
1518 ethSrc="",
1519 ethDst="",
1520 bandwidth="",
1521 lambdaAlloc=False,
1522 ipProto="",
1523 ipSrc="",
1524 ipDst="",
1525 tcpSrc="",
1526 tcpDst="",
1527 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001528 setEthDst="",
1529 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001530 """
1531 Note:
1532 This function assumes the format of all egress devices
1533 is same. That is, all egress devices include port numbers
1534 with a "/" or all egress devices could specify device
1535 ids and port numbers seperately.
1536 Required:
1537 * EgressDeviceList: List of device ids of egress device
1538 ( Atleast 2 eress devices required in the list )
1539 * ingressDevice: device id of ingress device
1540 Optional:
1541 * ethType: specify ethType
1542 * ethSrc: specify ethSrc ( i.e. src mac addr )
1543 * ethDst: specify ethDst ( i.e. dst mac addr )
1544 * bandwidth: specify bandwidth capacity of link
1545 * lambdaAlloc: if True, intent will allocate lambda
1546 for the specified intent
1547 * ipProto: specify ip protocol
1548 * ipSrc: specify ip source address
1549 * ipDst: specify ip destination address
1550 * tcpSrc: specify tcp source port
1551 * tcpDst: specify tcp destination port
1552 * setEthSrc: action to Rewrite Source MAC Address
1553 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001554 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001555 Description:
1556 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1557 specifying device id's and optional fields
1558 Returns:
1559 A string of the intent id or None on error
1560
1561 NOTE: This function may change depending on the
1562 options developers provide for singlepoint-to-multipoint
1563 intent via cli
1564 """
1565 try:
1566 # If there are no optional arguments
1567 if not ethType and not ethSrc and not ethDst\
1568 and not bandwidth and not lambdaAlloc\
1569 and not ipProto and not ipSrc and not ipDst\
1570 and not tcpSrc and not tcpDst and not setEthSrc\
1571 and not setEthDst:
1572 cmd = "add-single-to-multi-intent"
1573
1574 else:
1575 cmd = "add-single-to-multi-intent"
1576
1577 if ethType:
1578 cmd += " --ethType " + str( ethType )
1579 if ethSrc:
1580 cmd += " --ethSrc " + str( ethSrc )
1581 if ethDst:
1582 cmd += " --ethDst " + str( ethDst )
1583 if bandwidth:
1584 cmd += " --bandwidth " + str( bandwidth )
1585 if lambdaAlloc:
1586 cmd += " --lambda "
1587 if ipProto:
1588 cmd += " --ipProto " + str( ipProto )
1589 if ipSrc:
1590 cmd += " --ipSrc " + str( ipSrc )
1591 if ipDst:
1592 cmd += " --ipDst " + str( ipDst )
1593 if tcpSrc:
1594 cmd += " --tcpSrc " + str( tcpSrc )
1595 if tcpDst:
1596 cmd += " --tcpDst " + str( tcpDst )
1597 if setEthSrc:
1598 cmd += " --setEthSrc " + str( setEthSrc )
1599 if setEthDst:
1600 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001601 if vlanId:
1602 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001603
1604 # Check whether the user appended the port
1605 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001606
kelvin-onlabb9408212015-04-01 13:34:04 -07001607 if "/" in ingressDevice:
1608 cmd += " " + str( ingressDevice )
1609 else:
1610 if not portIngress:
1611 main.log.error( "You must specify " +
1612 "the Ingress port" )
1613 return main.FALSE
1614
1615 cmd += " " +\
1616 str( ingressDevice ) + "/" +\
1617 str( portIngress )
1618
1619 if portEgressList is None:
1620 for egressDevice in egressDeviceList:
1621 if "/" in egressDevice:
1622 cmd += " " + str( egressDevice )
1623 else:
1624 main.log.error( "You must specify " +
1625 "the egress port" )
1626 # TODO: perhaps more meaningful return
1627 return main.FALSE
1628 else:
1629 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001630 for egressDevice, portEgress in zip( egressDeviceList,
1631 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001632 cmd += " " + \
1633 str( egressDevice ) + "/" +\
1634 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001635 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001636 main.log.error( "Device list and port list does not " +
1637 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001638 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001639 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001640 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001641 # If error, return error message
1642 if re.search( "Error", handle ):
1643 main.log.error( "Error in adding singlepoint-to-multipoint " +
1644 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001645 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001646 else:
1647 match = re.search('id=0x([\da-f]+),', handle)
1648 if match:
1649 return match.group()[3:-1]
1650 else:
1651 main.log.error( "Error, intent ID not found" )
1652 return None
Jon Hallc6793552016-01-19 14:18:37 -08001653 except AssertionError:
1654 main.log.exception( "" )
1655 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001656 except TypeError:
1657 main.log.exception( self.name + ": Object not as expected" )
1658 return None
shahshreyad0c80432014-12-04 16:56:05 -08001659 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001660 main.log.error( self.name + ": EOF exception found" )
1661 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001662 main.cleanup()
1663 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001665 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001666 main.cleanup()
1667 main.exit()
1668
Hari Krishna9e232602015-04-13 17:29:08 -07001669 def addMplsIntent(
1670 self,
1671 ingressDevice,
1672 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001673 ingressPort="",
1674 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001675 ethType="",
1676 ethSrc="",
1677 ethDst="",
1678 bandwidth="",
1679 lambdaAlloc=False,
1680 ipProto="",
1681 ipSrc="",
1682 ipDst="",
1683 tcpSrc="",
1684 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001685 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001686 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001687 priority=""):
1688 """
1689 Required:
1690 * ingressDevice: device id of ingress device
1691 * egressDevice: device id of egress device
1692 Optional:
1693 * ethType: specify ethType
1694 * ethSrc: specify ethSrc ( i.e. src mac addr )
1695 * ethDst: specify ethDst ( i.e. dst mac addr )
1696 * bandwidth: specify bandwidth capacity of link
1697 * lambdaAlloc: if True, intent will allocate lambda
1698 for the specified intent
1699 * ipProto: specify ip protocol
1700 * ipSrc: specify ip source address
1701 * ipDst: specify ip destination address
1702 * tcpSrc: specify tcp source port
1703 * tcpDst: specify tcp destination port
1704 * ingressLabel: Ingress MPLS label
1705 * egressLabel: Egress MPLS label
1706 Description:
1707 Adds MPLS intent by
1708 specifying device id's and optional fields
1709 Returns:
1710 A string of the intent id or None on error
1711
1712 NOTE: This function may change depending on the
1713 options developers provide for MPLS
1714 intent via cli
1715 """
1716 try:
1717 # If there are no optional arguments
1718 if not ethType and not ethSrc and not ethDst\
1719 and not bandwidth and not lambdaAlloc \
1720 and not ipProto and not ipSrc and not ipDst \
1721 and not tcpSrc and not tcpDst and not ingressLabel \
1722 and not egressLabel:
1723 cmd = "add-mpls-intent"
1724
1725 else:
1726 cmd = "add-mpls-intent"
1727
1728 if ethType:
1729 cmd += " --ethType " + str( ethType )
1730 if ethSrc:
1731 cmd += " --ethSrc " + str( ethSrc )
1732 if ethDst:
1733 cmd += " --ethDst " + str( ethDst )
1734 if bandwidth:
1735 cmd += " --bandwidth " + str( bandwidth )
1736 if lambdaAlloc:
1737 cmd += " --lambda "
1738 if ipProto:
1739 cmd += " --ipProto " + str( ipProto )
1740 if ipSrc:
1741 cmd += " --ipSrc " + str( ipSrc )
1742 if ipDst:
1743 cmd += " --ipDst " + str( ipDst )
1744 if tcpSrc:
1745 cmd += " --tcpSrc " + str( tcpSrc )
1746 if tcpDst:
1747 cmd += " --tcpDst " + str( tcpDst )
1748 if ingressLabel:
1749 cmd += " --ingressLabel " + str( ingressLabel )
1750 if egressLabel:
1751 cmd += " --egressLabel " + str( egressLabel )
1752 if priority:
1753 cmd += " --priority " + str( priority )
1754
1755 # Check whether the user appended the port
1756 # or provided it as an input
1757 if "/" in ingressDevice:
1758 cmd += " " + str( ingressDevice )
1759 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001760 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001761 main.log.error( "You must specify the ingress port" )
1762 return None
1763
1764 cmd += " " + \
1765 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001766 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001767
1768 if "/" in egressDevice:
1769 cmd += " " + str( egressDevice )
1770 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001771 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001772 main.log.error( "You must specify the egress port" )
1773 return None
1774
1775 cmd += " " +\
1776 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001777 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001778
1779 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001780 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001781 # If error, return error message
1782 if re.search( "Error", handle ):
1783 main.log.error( "Error in adding mpls intent" )
1784 return None
1785 else:
1786 # TODO: print out all the options in this message?
1787 main.log.info( "MPLS intent installed between " +
1788 str( ingressDevice ) + " and " +
1789 str( egressDevice ) )
1790 match = re.search('id=0x([\da-f]+),', handle)
1791 if match:
1792 return match.group()[3:-1]
1793 else:
1794 main.log.error( "Error, intent ID not found" )
1795 return None
Jon Hallc6793552016-01-19 14:18:37 -08001796 except AssertionError:
1797 main.log.exception( "" )
1798 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001799 except TypeError:
1800 main.log.exception( self.name + ": Object not as expected" )
1801 return None
1802 except pexpect.EOF:
1803 main.log.error( self.name + ": EOF exception found" )
1804 main.log.error( self.name + ": " + self.handle.before )
1805 main.cleanup()
1806 main.exit()
1807 except Exception:
1808 main.log.exception( self.name + ": Uncaught exception!" )
1809 main.cleanup()
1810 main.exit()
1811
Jon Hallefbd9792015-03-05 16:11:36 -08001812 def removeIntent( self, intentId, app='org.onosproject.cli',
1813 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001814 """
shahshreya1c818fc2015-02-26 13:44:08 -08001815 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001816 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001817 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001818 -p or --purge: Purge the intent from the store after removal
1819
Jon Halle3f39ff2015-01-13 11:50:53 -08001820 Returns:
1821 main.False on error and
1822 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001823 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001824 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001825 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001826 if purge:
1827 cmdStr += " -p"
1828 if sync:
1829 cmdStr += " -s"
1830
1831 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001833 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001834 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001835 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001836 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001837 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001838 # TODO: Should this be main.TRUE
1839 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001840 except AssertionError:
1841 main.log.exception( "" )
1842 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001843 except TypeError:
1844 main.log.exception( self.name + ": Object not as expected" )
1845 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001846 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001847 main.log.error( self.name + ": EOF exception found" )
1848 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001849 main.cleanup()
1850 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001851 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001852 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001853 main.cleanup()
1854 main.exit()
1855
Jeremy42df2e72016-02-23 16:37:46 -08001856 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1857 """
1858 Description:
1859 Remove all the intents
1860 Optional args:-
1861 -s or --sync: Waits for the removal before returning
1862 -p or --purge: Purge the intent from the store after removal
1863 Returns:
1864 Returns main.TRUE if all intents are removed, otherwise returns
1865 main.FALSE; Returns None for exception
1866 """
1867 try:
1868 cmdStr = "remove-intent"
1869 if purge:
1870 cmdStr += " -p"
1871 if sync:
1872 cmdStr += " -s"
1873
1874 cmdStr += " " + app
1875 handle = self.sendline( cmdStr )
1876 assert "Command not found:" not in handle, handle
1877 if re.search( "Error", handle ):
1878 main.log.error( "Error in removing intent" )
1879 return main.FALSE
1880 else:
1881 return main.TRUE
1882 except AssertionError:
1883 main.log.exception( "" )
1884 return None
1885 except TypeError:
1886 main.log.exception( self.name + ": Object not as expected" )
1887 return None
1888 except pexpect.EOF:
1889 main.log.error( self.name + ": EOF exception found" )
1890 main.log.error( self.name + ": " + self.handle.before )
1891 main.cleanup()
1892 main.exit()
1893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
1895 main.cleanup()
1896 main.exit()
1897
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001898 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001899 """
1900 Purges all WITHDRAWN Intents
1901 """
1902 try:
1903 cmdStr = "purge-intents"
1904 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001905 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001906 if re.search( "Error", handle ):
1907 main.log.error( "Error in purging intents" )
1908 return main.FALSE
1909 else:
1910 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001911 except AssertionError:
1912 main.log.exception( "" )
1913 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001914 except TypeError:
1915 main.log.exception( self.name + ": Object not as expected" )
1916 return None
1917 except pexpect.EOF:
1918 main.log.error( self.name + ": EOF exception found" )
1919 main.log.error( self.name + ": " + self.handle.before )
1920 main.cleanup()
1921 main.exit()
1922 except Exception:
1923 main.log.exception( self.name + ": Uncaught exception!" )
1924 main.cleanup()
1925 main.exit()
1926
kelvin-onlabd3b64892015-01-20 13:26:24 -08001927 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001928 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001929 NOTE: This method should be used after installing application:
1930 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001931 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001932 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001933 Description:
1934 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001935 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001936 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001937 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001938 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001939 cmdStr += " -j"
1940 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001941 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001942 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001943 except AssertionError:
1944 main.log.exception( "" )
1945 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001946 except TypeError:
1947 main.log.exception( self.name + ": Object not as expected" )
1948 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001950 main.log.error( self.name + ": EOF exception found" )
1951 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001952 main.cleanup()
1953 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001954 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001955 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001956 main.cleanup()
1957 main.exit()
1958
pingping-lin54b03372015-08-13 14:43:10 -07001959 def ipv4RouteNumber( self ):
1960 """
1961 NOTE: This method should be used after installing application:
1962 onos-app-sdnip
1963 Description:
1964 Obtain the total IPv4 routes number in the system
1965 """
1966 try:
1967 cmdStr = "routes -s -j"
1968 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001969 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001970 jsonResult = json.loads( handle )
1971 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001972 except AssertionError:
1973 main.log.exception( "" )
1974 return None
1975 except ( TypeError, ValueError ):
1976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001977 return None
1978 except pexpect.EOF:
1979 main.log.error( self.name + ": EOF exception found" )
1980 main.log.error( self.name + ": " + self.handle.before )
1981 main.cleanup()
1982 main.exit()
1983 except Exception:
1984 main.log.exception( self.name + ": Uncaught exception!" )
1985 main.cleanup()
1986 main.exit()
1987
pingping-lin8244a3b2015-09-16 13:36:56 -07001988 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001989 """
andrewonlabe6745342014-10-17 14:29:13 -04001990 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001991 Obtain intents from the ONOS cli.
1992 Optional:
1993 * jsonFormat: Enable output formatting in json, default to True
1994 * summary: Whether only output the intent summary, defaults to False
1995 * type: Only output a certain type of intent. This options is valid
1996 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001997 """
andrewonlabe6745342014-10-17 14:29:13 -04001998 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001999 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002000 if summary:
2001 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002002 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002003 cmdStr += " -j"
2004 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002005 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002006 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002007 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002008 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002009 else:
Jon Hallff566d52016-01-15 14:45:36 -08002010 intentType = ""
2011 # IF we want the summary of a specific intent type
2012 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002013 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002014 if intentType in jsonResult.keys():
2015 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002016 else:
Jon Hallff566d52016-01-15 14:45:36 -08002017 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002018 return handle
2019 else:
2020 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002021 except AssertionError:
2022 main.log.exception( "" )
2023 return None
2024 except ( TypeError, ValueError ):
2025 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002026 return None
2027 except pexpect.EOF:
2028 main.log.error( self.name + ": EOF exception found" )
2029 main.log.error( self.name + ": " + self.handle.before )
2030 main.cleanup()
2031 main.exit()
2032 except Exception:
2033 main.log.exception( self.name + ": Uncaught exception!" )
2034 main.cleanup()
2035 main.exit()
2036
kelvin-onlab54400a92015-02-26 18:05:51 -08002037 def getIntentState(self, intentsId, intentsJson=None):
2038 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002039 Check intent state.
2040 Accepts a single intent ID (string type) or a list of intent IDs.
2041 Returns the state(string type) of the id if a single intent ID is
2042 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08002043 Returns a dictionary with intent IDs as the key and its
2044 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08002045 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08002046 intentId: intent ID (string type)
2047 intentsJson: parsed json object from the onos:intents api
2048 Returns:
2049 state = An intent's state- INSTALL,WITHDRAWN etc.
2050 stateDict = Dictionary of intent's state. intent ID as the keys and
2051 state as the values.
2052 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002053 try:
2054 state = "State is Undefined"
2055 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002056 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002057 else:
Jon Hallc6793552016-01-19 14:18:37 -08002058 rawJson = intentsJson
2059 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002060 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002061 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002062 if intentsId == intent[ 'id' ]:
2063 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002064 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002065 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2066 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002067 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002068 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002069 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002070 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002071 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002072 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002073 if intentsId[ i ] == intents[ 'id' ]:
2074 stateDict[ 'state' ] = intents[ 'state' ]
2075 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002076 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 break
Jon Hallefbd9792015-03-05 16:11:36 -08002078 if len( intentsId ) != len( dictList ):
2079 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002080 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002081 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002082 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002083 return None
Jon Hallc6793552016-01-19 14:18:37 -08002084 except ( TypeError, ValueError ):
2085 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002086 return None
2087 except pexpect.EOF:
2088 main.log.error( self.name + ": EOF exception found" )
2089 main.log.error( self.name + ": " + self.handle.before )
2090 main.cleanup()
2091 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002092 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002093 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002094 main.cleanup()
2095 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002096
kelvin-onlabf512e942015-06-08 19:42:59 -07002097 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 """
2099 Description:
2100 Check intents state
2101 Required:
2102 intentsId - List of intents ID to be checked
2103 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002104 expectedState - Check the expected state(s) of each intents
2105 state in the list.
2106 *NOTE: You can pass in a list of expected state,
2107 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002108 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002109 Returns main.TRUE only if all intent are the same as expected states
2110 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002111 """
2112 try:
2113 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002114 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002115 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002116 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002117 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 "getting intents state" )
2119 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002120
2121 if isinstance( expectedState, types.StringType ):
2122 for intents in intentsDict:
2123 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002124 main.log.debug( self.name + " : Intent ID - " +
2125 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002126 " actual state = " +
2127 intents.get( 'state' )
2128 + " does not equal expected state = "
2129 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002130 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002131
2132 elif isinstance( expectedState, types.ListType ):
2133 for intents in intentsDict:
2134 if not any( state == intents.get( 'state' ) for state in
2135 expectedState ):
2136 main.log.debug( self.name + " : Intent ID - " +
2137 intents.get( 'id' ) +
2138 " actual state = " +
2139 intents.get( 'state' ) +
2140 " does not equal expected states = "
2141 + str( expectedState ) )
2142 returnValue = main.FALSE
2143
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002144 if returnValue == main.TRUE:
2145 main.log.info( self.name + ": All " +
2146 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002147 " intents are in " + str( expectedState ) +
2148 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002149 return returnValue
2150 except TypeError:
2151 main.log.exception( self.name + ": Object not as expected" )
2152 return None
2153 except pexpect.EOF:
2154 main.log.error( self.name + ": EOF exception found" )
2155 main.log.error( self.name + ": " + self.handle.before )
2156 main.cleanup()
2157 main.exit()
2158 except Exception:
2159 main.log.exception( self.name + ": Uncaught exception!" )
2160 main.cleanup()
2161 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002162
GlennRCed771242016-01-13 17:02:47 -08002163 def checkIntentSummary( self, timeout=60 ):
2164 """
2165 Description:
2166 Check the number of installed intents.
2167 Optional:
2168 timeout - the timeout for pexcept
2169 Return:
2170 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2171 , otherwise, returns main.FALSE.
2172 """
2173
2174 try:
2175 cmd = "intents -s -j"
2176
2177 # Check response if something wrong
2178 response = self.sendline( cmd, timeout=timeout )
2179 if response == None:
2180 return main.False
2181 response = json.loads( response )
2182
2183 # get total and installed number, see if they are match
2184 allState = response.get( 'all' )
2185 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002186 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002187 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002188 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002189 return main.FALSE
2190
Jon Hallc6793552016-01-19 14:18:37 -08002191 except ( TypeError, ValueError ):
2192 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002193 return None
2194 except pexpect.EOF:
2195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
2197 main.cleanup()
2198 main.exit()
2199 except Exception:
2200 main.log.exception( self.name + ": Uncaught exception!" )
2201 main.cleanup()
2202 main.exit()
2203
2204 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002205 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002206 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002207 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002208 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002209 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002210 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002211 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002212 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002214 cmdStr += " -j "
2215 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002216 handle = self.sendline( cmdStr, timeout=timeout )
2217 assert "Command not found:" not in handle, handle
2218 if re.search( "Error:", handle ):
2219 main.log.error( self.name + ": flows() response: " +
2220 str( handle ) )
2221 return handle
2222 except AssertionError:
2223 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002224 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002225 except TypeError:
2226 main.log.exception( self.name + ": Object not as expected" )
2227 return None
Jon Hallc6793552016-01-19 14:18:37 -08002228 except pexpect.TIMEOUT:
2229 main.log.error( self.name + ": ONOS timeout" )
2230 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002232 main.log.error( self.name + ": EOF exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002234 main.cleanup()
2235 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002236 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002237 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002238 main.cleanup()
2239 main.exit()
2240
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002241 def checkFlowCount(self, min=0, timeout=60 ):
2242 count = int(self.getTotalFlowsNum( timeout=timeout ))
2243 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002244
Jon Hallc6793552016-01-19 14:18:37 -08002245 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002246 """
2247 Description:
GlennRCed771242016-01-13 17:02:47 -08002248 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002249 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2250 if the count of those states is 0, which means all current flows
2251 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002252 Optional:
GlennRCed771242016-01-13 17:02:47 -08002253 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002254 Return:
2255 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002256 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002257 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002258 """
2259 try:
GlennRCed771242016-01-13 17:02:47 -08002260 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2261 checkedStates = []
2262 statesCount = [0, 0, 0, 0]
2263 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002264 rawFlows = self.flows( state=s, timeout = timeout )
2265 checkedStates.append( json.loads( rawFlows ) )
2266 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002267 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002268 try:
2269 statesCount[i] += int( c.get( "flowCount" ) )
2270 except TypeError:
2271 main.log.exception( "Json object not as expected" )
2272 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002273
GlennRCed771242016-01-13 17:02:47 -08002274 # We want to count PENDING_ADD if isPENDING is true
2275 if isPENDING:
2276 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2277 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002278 else:
GlennRCed771242016-01-13 17:02:47 -08002279 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2280 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002281 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002282 except ( TypeError, ValueError ):
2283 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002284 return None
2285 except pexpect.EOF:
2286 main.log.error( self.name + ": EOF exception found" )
2287 main.log.error( self.name + ": " + self.handle.before )
2288 main.cleanup()
2289 main.exit()
2290 except Exception:
2291 main.log.exception( self.name + ": Uncaught exception!" )
2292 main.cleanup()
2293 main.exit()
2294
GlennRCed771242016-01-13 17:02:47 -08002295 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2296 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002297 """
andrewonlab87852b02014-11-19 18:44:19 -05002298 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002299 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002300 a specific point-to-point intent definition
2301 Required:
GlennRCed771242016-01-13 17:02:47 -08002302 * ingress: specify source dpid
2303 * egress: specify destination dpid
2304 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002305 Optional:
GlennRCed771242016-01-13 17:02:47 -08002306 * offset: the keyOffset is where the next batch of intents
2307 will be installed
2308 Returns: If failed to push test intents, it will returen None,
2309 if successful, return true.
2310 Timeout expection will return None,
2311 TypeError will return false
2312 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002313 """
andrewonlab87852b02014-11-19 18:44:19 -05002314 try:
GlennRCed771242016-01-13 17:02:47 -08002315 if background:
2316 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002317 else:
GlennRCed771242016-01-13 17:02:47 -08002318 back = ""
2319 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002320 ingress,
2321 egress,
2322 batchSize,
2323 offset,
2324 back )
GlennRCed771242016-01-13 17:02:47 -08002325 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002326 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002327 main.log.info( response )
2328 if response == None:
2329 return None
2330
2331 # TODO: We should handle if there is failure in installation
2332 return main.TRUE
2333
Jon Hallc6793552016-01-19 14:18:37 -08002334 except AssertionError:
2335 main.log.exception( "" )
2336 return None
GlennRCed771242016-01-13 17:02:47 -08002337 except pexpect.TIMEOUT:
2338 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002339 return None
andrewonlab87852b02014-11-19 18:44:19 -05002340 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002341 main.log.error( self.name + ": EOF exception found" )
2342 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002343 main.cleanup()
2344 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002345 except TypeError:
2346 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002347 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002348 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002349 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002350 main.cleanup()
2351 main.exit()
2352
YPZhangf6f14a02016-01-28 15:17:31 -08002353 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002354 """
2355 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002356 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002357 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002358 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002359 """
YPZhange3109a72016-02-02 11:25:37 -08002360
YPZhangb5d3f832016-01-23 22:54:26 -08002361 try:
YPZhange3109a72016-02-02 11:25:37 -08002362 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002363 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002364 totalFlows = self.sendline( cmd, timeout=timeout )
2365
2366 if totalFlows == None:
2367 # if timeout, we will get total number of all flows, and subtract other states
2368 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2369 checkedStates = []
2370 totalFlows = 0
2371 statesCount = [0, 0, 0, 0]
2372
2373 # get total flows from summary
2374 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2375 totalFlows = int( response.get("flows") )
2376
2377 for s in states:
2378 rawFlows = self.flows( state=s, timeout = timeout )
2379 if rawFlows == None:
2380 # if timeout, return the total flows number from summary command
2381 return totalFlows
2382 checkedStates.append( json.loads( rawFlows ) )
2383
2384 # Calculate ADDED flows number, equal total subtracts others
2385 for i in range( len( states ) ):
2386 for c in checkedStates[i]:
2387 try:
2388 statesCount[i] += int( c.get( "flowCount" ) )
2389 except TypeError:
2390 main.log.exception( "Json object not as expected" )
2391 totalFlows = totalFlows - int( statesCount[i] )
2392 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2393
2394 return totalFlows
2395
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002396 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002397
YPZhangb5d3f832016-01-23 22:54:26 -08002398 except TypeError:
2399 main.log.exception( self.name + ": Object not as expected" )
2400 return None
2401 except pexpect.EOF:
2402 main.log.error( self.name + ": EOF exception found" )
2403 main.log.error( self.name + ": " + self.handle.before )
2404 main.cleanup()
2405 main.exit()
2406 except Exception:
2407 main.log.exception( self.name + ": Uncaught exception!" )
2408 main.cleanup()
2409 main.exit()
2410
2411 def getTotalIntentsNum( self ):
2412 """
2413 Description:
2414 Get the total number of intents, include every states.
2415 Return:
2416 The number of intents
2417 """
2418 try:
2419 cmd = "summary -j"
2420 response = self.sendline( cmd )
2421 if response == None:
2422 return -1
2423 response = json.loads( response )
2424 return int( response.get("intents") )
2425 except TypeError:
2426 main.log.exception( self.name + ": Object not as expected" )
2427 return None
2428 except pexpect.EOF:
2429 main.log.error( self.name + ": EOF exception found" )
2430 main.log.error( self.name + ": " + self.handle.before )
2431 main.cleanup()
2432 main.exit()
2433 except Exception:
2434 main.log.exception( self.name + ": Uncaught exception!" )
2435 main.cleanup()
2436 main.exit()
2437
kelvin-onlabd3b64892015-01-20 13:26:24 -08002438 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002439 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002440 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002441 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002442 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002443 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002444 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002445 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002446 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002447 cmdStr += " -j"
2448 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002449 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002450 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002451 except AssertionError:
2452 main.log.exception( "" )
2453 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002454 except TypeError:
2455 main.log.exception( self.name + ": Object not as expected" )
2456 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002457 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002458 main.log.error( self.name + ": EOF exception found" )
2459 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002460 main.cleanup()
2461 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002462 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002463 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002464 main.cleanup()
2465 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002466
kelvin-onlabd3b64892015-01-20 13:26:24 -08002467 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002468 """
2469 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002470 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002472 """
andrewonlab867212a2014-10-22 20:13:38 -04002473 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002474 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002475 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002476 cmdStr += " -j"
2477 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002478 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002479 if handle:
2480 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002481 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002482 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002483 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002484 else:
2485 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002486 except AssertionError:
2487 main.log.exception( "" )
2488 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002489 except TypeError:
2490 main.log.exception( self.name + ": Object not as expected" )
2491 return None
andrewonlab867212a2014-10-22 20:13:38 -04002492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002493 main.log.error( self.name + ": EOF exception found" )
2494 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002495 main.cleanup()
2496 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002497 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002498 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002499 main.cleanup()
2500 main.exit()
2501
kelvin8ec71442015-01-15 16:57:00 -08002502 # Wrapper functions ****************
2503 # Wrapper functions use existing driver
2504 # functions and extends their use case.
2505 # For example, we may use the output of
2506 # a normal driver function, and parse it
2507 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002508
kelvin-onlabd3b64892015-01-20 13:26:24 -08002509 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002510 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002511 Description:
2512 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002513 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002514 try:
kelvin8ec71442015-01-15 16:57:00 -08002515 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002516 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002517 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002518
kelvin8ec71442015-01-15 16:57:00 -08002519 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002520 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2521 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002522 match = re.search('id=0x([\da-f]+),', intents)
2523 if match:
2524 tmpId = match.group()[3:-1]
2525 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002526 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002527
Jon Halld4d4b372015-01-28 16:02:41 -08002528 except TypeError:
2529 main.log.exception( self.name + ": Object not as expected" )
2530 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002532 main.log.error( self.name + ": EOF exception found" )
2533 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002534 main.cleanup()
2535 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002536 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002537 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002538 main.cleanup()
2539 main.exit()
2540
Jon Hall30b82fa2015-03-04 17:15:43 -08002541 def FlowAddedCount( self, deviceId ):
2542 """
2543 Determine the number of flow rules for the given device id that are
2544 in the added state
2545 """
2546 try:
2547 cmdStr = "flows any " + str( deviceId ) + " | " +\
2548 "grep 'state=ADDED' | wc -l"
2549 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002550 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002551 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002552 except AssertionError:
2553 main.log.exception( "" )
2554 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002555 except pexpect.EOF:
2556 main.log.error( self.name + ": EOF exception found" )
2557 main.log.error( self.name + ": " + self.handle.before )
2558 main.cleanup()
2559 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002560 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002561 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002562 main.cleanup()
2563 main.exit()
2564
kelvin-onlabd3b64892015-01-20 13:26:24 -08002565 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002566 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002567 Use 'devices' function to obtain list of all devices
2568 and parse the result to obtain a list of all device
2569 id's. Returns this list. Returns empty list if no
2570 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002571 List is ordered sequentially
2572
andrewonlab3e15ead2014-10-15 14:21:34 -04002573 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002574 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002575 the ids. By obtaining the list of device ids on the fly,
2576 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002577 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002578 try:
kelvin8ec71442015-01-15 16:57:00 -08002579 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002580 devicesStr = self.devices( jsonFormat=False )
2581 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002582
kelvin-onlabd3b64892015-01-20 13:26:24 -08002583 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002584 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002585 return idList
kelvin8ec71442015-01-15 16:57:00 -08002586
2587 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002588 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002589 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002590 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002591 # Split list further into arguments before and after string
2592 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 # append to idList
2594 for arg in tempList:
2595 idList.append( arg.split( "id=" )[ 1 ] )
2596 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002597
Jon Halld4d4b372015-01-28 16:02:41 -08002598 except TypeError:
2599 main.log.exception( self.name + ": Object not as expected" )
2600 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002601 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002602 main.log.error( self.name + ": EOF exception found" )
2603 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002604 main.cleanup()
2605 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002606 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002607 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002608 main.cleanup()
2609 main.exit()
2610
kelvin-onlabd3b64892015-01-20 13:26:24 -08002611 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002612 """
andrewonlab7c211572014-10-15 16:45:20 -04002613 Uses 'nodes' function to obtain list of all nodes
2614 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002615 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002616 Returns:
2617 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002618 """
andrewonlab7c211572014-10-15 16:45:20 -04002619 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002620 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002621 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002622 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002623 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002624 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002625 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002626 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002627 nodesJson = json.loads( nodesStr )
2628 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002629 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002630 except ( TypeError, ValueError ):
2631 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002632 return None
andrewonlab7c211572014-10-15 16:45:20 -04002633 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002634 main.log.error( self.name + ": EOF exception found" )
2635 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002636 main.cleanup()
2637 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002638 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002639 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002640 main.cleanup()
2641 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002642
kelvin-onlabd3b64892015-01-20 13:26:24 -08002643 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002644 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002645 Return the first device from the devices api whose 'id' contains 'dpid'
2646 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002647 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002648 try:
kelvin8ec71442015-01-15 16:57:00 -08002649 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002650 return None
2651 else:
kelvin8ec71442015-01-15 16:57:00 -08002652 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 rawDevices = self.devices()
2654 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002655 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002656 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002657 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2658 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002659 return device
2660 return None
Jon Hallc6793552016-01-19 14:18:37 -08002661 except ( TypeError, ValueError ):
2662 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002663 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002665 main.log.error( self.name + ": EOF exception found" )
2666 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002667 main.cleanup()
2668 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002669 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002670 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002671 main.cleanup()
2672 main.exit()
2673
You Wang24139872016-05-03 11:48:47 -07002674 def getTopology( self, topologyOutput ):
2675 """
2676 Definition:
2677 Loads a json topology output
2678 Return:
2679 topology = current ONOS topology
2680 """
2681 import json
2682 try:
2683 # either onos:topology or 'topology' will work in CLI
2684 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002685 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002686 return topology
2687 except pexpect.EOF:
2688 main.log.error( self.name + ": EOF exception found" )
2689 main.log.error( self.name + ": " + self.handle.before )
2690 main.cleanup()
2691 main.exit()
2692 except Exception:
2693 main.log.exception( self.name + ": Uncaught exception!" )
2694 main.cleanup()
2695 main.exit()
2696
2697 def checkStatus(
2698 self,
2699 topologyResult,
2700 numoswitch,
2701 numolink,
2702 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002703 """
Jon Hallefbd9792015-03-05 16:11:36 -08002704 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002705 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002706 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002707
You Wang24139872016-05-03 11:48:47 -07002708 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002709 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002710 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002711 logLevel = level to log to.
2712 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002713
Jon Hallefbd9792015-03-05 16:11:36 -08002714 Returns: main.TRUE if the number of switches and links are correct,
2715 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002716 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002717 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002718 try:
You Wang24139872016-05-03 11:48:47 -07002719 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002720 if topology == {}:
2721 return main.ERROR
2722 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002723 # Is the number of switches is what we expected
2724 devices = topology.get( 'devices', False )
2725 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002726 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002727 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002728 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002729 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002731 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002732 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002733 output = output + "The number of links and switches match "\
2734 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002735 result = main.TRUE
2736 else:
You Wang24139872016-05-03 11:48:47 -07002737 output = output + \
2738 "The number of links and switches does not match " + \
2739 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002740 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002741 output = output + "\n ONOS sees %i devices" % int( devices )
2742 output = output + " (%i expected) " % int( numoswitch )
2743 output = output + "and %i links " % int( links )
2744 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002745 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002746 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002748 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002749 else:
You Wang24139872016-05-03 11:48:47 -07002750 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002751 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002753 main.log.error( self.name + ": EOF exception found" )
2754 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002755 main.cleanup()
2756 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002757 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002758 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002759 main.cleanup()
2760 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002761
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002763 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002764 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002765 deviceId must be the id of a device as seen in the onos devices command
2766 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002767 role must be either master, standby, or none
2768
Jon Halle3f39ff2015-01-13 11:50:53 -08002769 Returns:
2770 main.TRUE or main.FALSE based on argument verification and
2771 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002772 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002773 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002774 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002775 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002776 cmdStr = "device-role " +\
2777 str( deviceId ) + " " +\
2778 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002779 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002780 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002781 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002782 if re.search( "Error", handle ):
2783 # end color output to escape any colours
2784 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002785 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002786 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002787 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002788 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002789 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002790 main.log.error( "Invalid 'role' given to device_role(). " +
2791 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002792 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002793 except AssertionError:
2794 main.log.exception( "" )
2795 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002796 except TypeError:
2797 main.log.exception( self.name + ": Object not as expected" )
2798 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002799 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002800 main.log.error( self.name + ": EOF exception found" )
2801 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002802 main.cleanup()
2803 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002804 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002805 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002806 main.cleanup()
2807 main.exit()
2808
kelvin-onlabd3b64892015-01-20 13:26:24 -08002809 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002810 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002811 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002812 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002814 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002815 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002816 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002818 cmdStr += " -j"
2819 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002820 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002821 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002822 except AssertionError:
2823 main.log.exception( "" )
2824 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002825 except TypeError:
2826 main.log.exception( self.name + ": Object not as expected" )
2827 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002828 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002829 main.log.error( self.name + ": EOF exception found" )
2830 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002831 main.cleanup()
2832 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002833 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002834 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002835 main.cleanup()
2836 main.exit()
2837
kelvin-onlabd3b64892015-01-20 13:26:24 -08002838 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002839 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002840 CLI command to get the current leader for the Election test application
2841 NOTE: Requires installation of the onos-app-election feature
2842 Returns: Node IP of the leader if one exists
2843 None if none exists
2844 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002845 """
Jon Hall94fd0472014-12-08 11:52:42 -08002846 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 cmdStr = "election-test-leader"
2848 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002849 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002850 # Leader
2851 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002852 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 nodeSearch = re.search( leaderPattern, response )
2854 if nodeSearch:
2855 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002856 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002857 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002858 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002859 # no leader
2860 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002861 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002862 nullSearch = re.search( nullPattern, response )
2863 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002864 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002865 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002866 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002867 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002868 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002869 if re.search( errorPattern, response ):
2870 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002871 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002872 return main.FALSE
2873 else:
Jon Hall390696c2015-05-05 17:13:41 -07002874 main.log.error( "Error in electionTestLeader on " + self.name +
2875 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002876 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002877 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002878 except AssertionError:
2879 main.log.exception( "" )
2880 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002881 except TypeError:
2882 main.log.exception( self.name + ": Object not as expected" )
2883 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002884 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002885 main.log.error( self.name + ": EOF exception found" )
2886 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002887 main.cleanup()
2888 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002889 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002890 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002891 main.cleanup()
2892 main.exit()
2893
kelvin-onlabd3b64892015-01-20 13:26:24 -08002894 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002896 CLI command to run for leadership of the Election test application.
2897 NOTE: Requires installation of the onos-app-election feature
2898 Returns: Main.TRUE on success
2899 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002900 """
Jon Hall94fd0472014-12-08 11:52:42 -08002901 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002902 cmdStr = "election-test-run"
2903 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002904 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002905 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002906 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002907 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002908 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002909 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002910 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002911 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002912 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002913 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002914 errorPattern = "Command\snot\sfound"
2915 if re.search( errorPattern, response ):
2916 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002917 return main.FALSE
2918 else:
Jon Hall390696c2015-05-05 17:13:41 -07002919 main.log.error( "Error in electionTestRun on " + self.name +
2920 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002921 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002922 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002923 except AssertionError:
2924 main.log.exception( "" )
2925 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002926 except TypeError:
2927 main.log.exception( self.name + ": Object not as expected" )
2928 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002930 main.log.error( self.name + ": EOF exception found" )
2931 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002932 main.cleanup()
2933 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002935 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002936 main.cleanup()
2937 main.exit()
2938
kelvin-onlabd3b64892015-01-20 13:26:24 -08002939 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002940 """
Jon Hall94fd0472014-12-08 11:52:42 -08002941 * CLI command to withdraw the local node from leadership election for
2942 * the Election test application.
2943 #NOTE: Requires installation of the onos-app-election feature
2944 Returns: Main.TRUE on success
2945 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002946 """
Jon Hall94fd0472014-12-08 11:52:42 -08002947 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002948 cmdStr = "election-test-withdraw"
2949 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002950 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002951 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002952 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002953 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002954 if re.search( successPattern, response ):
2955 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002956 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002957 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002958 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002959 errorPattern = "Command\snot\sfound"
2960 if re.search( errorPattern, response ):
2961 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002962 return main.FALSE
2963 else:
Jon Hall390696c2015-05-05 17:13:41 -07002964 main.log.error( "Error in electionTestWithdraw on " +
2965 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002966 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002967 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002968 except AssertionError:
2969 main.log.exception( "" )
2970 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002971 except TypeError:
2972 main.log.exception( self.name + ": Object not as expected" )
2973 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002974 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002977 main.cleanup()
2978 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002979 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002980 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002981 main.cleanup()
2982 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002983
kelvin8ec71442015-01-15 16:57:00 -08002984 def getDevicePortsEnabledCount( self, dpid ):
2985 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002986 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002987 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002988 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002989 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002990 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2991 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002992 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002993 if re.search( "No such device", output ):
2994 main.log.error( "Error in getting ports" )
2995 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002996 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002997 return output
Jon Hallc6793552016-01-19 14:18:37 -08002998 except AssertionError:
2999 main.log.exception( "" )
3000 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003001 except TypeError:
3002 main.log.exception( self.name + ": Object not as expected" )
3003 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003005 main.log.error( self.name + ": EOF exception found" )
3006 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003007 main.cleanup()
3008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003010 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003011 main.cleanup()
3012 main.exit()
3013
kelvin8ec71442015-01-15 16:57:00 -08003014 def getDeviceLinksActiveCount( self, dpid ):
3015 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003016 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003017 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003018 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003019 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003020 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3021 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003022 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003023 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003024 main.log.error( "Error in getting ports " )
3025 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003026 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003027 return output
Jon Hallc6793552016-01-19 14:18:37 -08003028 except AssertionError:
3029 main.log.exception( "" )
3030 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003031 except TypeError:
3032 main.log.exception( self.name + ": Object not as expected" )
3033 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003034 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003035 main.log.error( self.name + ": EOF exception found" )
3036 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003037 main.cleanup()
3038 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003039 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003040 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003041 main.cleanup()
3042 main.exit()
3043
kelvin8ec71442015-01-15 16:57:00 -08003044 def getAllIntentIds( self ):
3045 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003046 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003047 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003048 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003049 cmdStr = "onos:intents | grep id="
3050 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003051 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003052 if re.search( "Error", output ):
3053 main.log.error( "Error in getting ports" )
3054 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003055 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003056 return output
Jon Hallc6793552016-01-19 14:18:37 -08003057 except AssertionError:
3058 main.log.exception( "" )
3059 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003060 except TypeError:
3061 main.log.exception( self.name + ": Object not as expected" )
3062 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003063 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003064 main.log.error( self.name + ": EOF exception found" )
3065 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003066 main.cleanup()
3067 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003068 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003069 main.log.exception( self.name + ": Uncaught exception!" )
3070 main.cleanup()
3071 main.exit()
3072
Jon Hall73509952015-02-24 16:42:56 -08003073 def intentSummary( self ):
3074 """
Jon Hallefbd9792015-03-05 16:11:36 -08003075 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003076 """
3077 try:
3078 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003079 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003080 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003081 states.append( intent.get( 'state', None ) )
3082 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003083 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003084 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003085 except ( TypeError, ValueError ):
3086 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003087 return None
3088 except pexpect.EOF:
3089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
3091 main.cleanup()
3092 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003093 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003094 main.log.exception( self.name + ": Uncaught exception!" )
3095 main.cleanup()
3096 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003097
Jon Hall61282e32015-03-19 11:34:11 -07003098 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003099 """
3100 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003101 Optional argument:
3102 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003103 """
Jon Hall63604932015-02-26 17:09:50 -08003104 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003105 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003106 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003107 cmdStr += " -j"
3108 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003109 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003110 return output
Jon Hallc6793552016-01-19 14:18:37 -08003111 except AssertionError:
3112 main.log.exception( "" )
3113 return None
Jon Hall63604932015-02-26 17:09:50 -08003114 except TypeError:
3115 main.log.exception( self.name + ": Object not as expected" )
3116 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003117 except pexpect.EOF:
3118 main.log.error( self.name + ": EOF exception found" )
3119 main.log.error( self.name + ": " + self.handle.before )
3120 main.cleanup()
3121 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003122 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003123 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003124 main.cleanup()
3125 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003126
acsmarsa4a4d1e2015-07-10 16:01:24 -07003127 def leaderCandidates( self, jsonFormat=True ):
3128 """
3129 Returns the output of the leaders -c command.
3130 Optional argument:
3131 * jsonFormat - boolean indicating if you want output in json
3132 """
3133 try:
3134 cmdStr = "onos:leaders -c"
3135 if jsonFormat:
3136 cmdStr += " -j"
3137 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003138 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003139 return output
Jon Hallc6793552016-01-19 14:18:37 -08003140 except AssertionError:
3141 main.log.exception( "" )
3142 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003143 except TypeError:
3144 main.log.exception( self.name + ": Object not as expected" )
3145 return None
3146 except pexpect.EOF:
3147 main.log.error( self.name + ": EOF exception found" )
3148 main.log.error( self.name + ": " + self.handle.before )
3149 main.cleanup()
3150 main.exit()
3151 except Exception:
3152 main.log.exception( self.name + ": Uncaught exception!" )
3153 main.cleanup()
3154 main.exit()
3155
Jon Hallc6793552016-01-19 14:18:37 -08003156 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003157 """
3158 Returns a list in format [leader,candidate1,candidate2,...] for a given
3159 topic parameter and an empty list if the topic doesn't exist
3160 If no leader is elected leader in the returned list will be "none"
3161 Returns None if there is a type error processing the json object
3162 """
3163 try:
Jon Hall6e709752016-02-01 13:38:46 -08003164 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003165 rawOutput = self.sendline( cmdStr )
3166 assert "Command not found:" not in rawOutput, rawOutput
3167 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003168 results = []
3169 for dict in output:
3170 if dict["topic"] == topic:
3171 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003172 candidates = re.split( ", ", dict["candidates"][1:-1] )
3173 results.append( leader )
3174 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003175 return results
Jon Hallc6793552016-01-19 14:18:37 -08003176 except AssertionError:
3177 main.log.exception( "" )
3178 return None
3179 except ( TypeError, ValueError ):
3180 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003181 return None
3182 except pexpect.EOF:
3183 main.log.error( self.name + ": EOF exception found" )
3184 main.log.error( self.name + ": " + self.handle.before )
3185 main.cleanup()
3186 main.exit()
3187 except Exception:
3188 main.log.exception( self.name + ": Uncaught exception!" )
3189 main.cleanup()
3190 main.exit()
3191
Jon Hall61282e32015-03-19 11:34:11 -07003192 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003193 """
3194 Returns the output of the intent Pending map.
3195 """
Jon Hall63604932015-02-26 17:09:50 -08003196 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003197 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003198 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003199 cmdStr += " -j"
3200 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003201 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003202 return output
Jon Hallc6793552016-01-19 14:18:37 -08003203 except AssertionError:
3204 main.log.exception( "" )
3205 return None
Jon Hall63604932015-02-26 17:09:50 -08003206 except TypeError:
3207 main.log.exception( self.name + ": Object not as expected" )
3208 return None
3209 except pexpect.EOF:
3210 main.log.error( self.name + ": EOF exception found" )
3211 main.log.error( self.name + ": " + self.handle.before )
3212 main.cleanup()
3213 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003214 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003215 main.log.exception( self.name + ": Uncaught exception!" )
3216 main.cleanup()
3217 main.exit()
3218
Jon Hall61282e32015-03-19 11:34:11 -07003219 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003220 """
3221 Returns the output of the raft partitions command for ONOS.
3222 """
Jon Hall61282e32015-03-19 11:34:11 -07003223 # Sample JSON
3224 # {
3225 # "leader": "tcp://10.128.30.11:7238",
3226 # "members": [
3227 # "tcp://10.128.30.11:7238",
3228 # "tcp://10.128.30.17:7238",
3229 # "tcp://10.128.30.13:7238",
3230 # ],
3231 # "name": "p1",
3232 # "term": 3
3233 # },
Jon Hall63604932015-02-26 17:09:50 -08003234 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003235 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003236 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003237 cmdStr += " -j"
3238 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003239 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003240 return output
Jon Hallc6793552016-01-19 14:18:37 -08003241 except AssertionError:
3242 main.log.exception( "" )
3243 return None
Jon Hall63604932015-02-26 17:09:50 -08003244 except TypeError:
3245 main.log.exception( self.name + ": Object not as expected" )
3246 return None
3247 except pexpect.EOF:
3248 main.log.error( self.name + ": EOF exception found" )
3249 main.log.error( self.name + ": " + self.handle.before )
3250 main.cleanup()
3251 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003252 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003253 main.log.exception( self.name + ": Uncaught exception!" )
3254 main.cleanup()
3255 main.exit()
3256
Jon Hallbe379602015-03-24 13:39:32 -07003257 def apps( self, jsonFormat=True ):
3258 """
3259 Returns the output of the apps command for ONOS. This command lists
3260 information about installed ONOS applications
3261 """
3262 # Sample JSON object
3263 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3264 # "description":"ONOS OpenFlow protocol southbound providers",
3265 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3266 # "features":"[onos-openflow]","state":"ACTIVE"}]
3267 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003268 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003269 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003270 cmdStr += " -j"
3271 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003272 assert "Command not found:" not in output, output
3273 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003274 return output
Jon Hallbe379602015-03-24 13:39:32 -07003275 # FIXME: look at specific exceptions/Errors
3276 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003277 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003278 return None
3279 except TypeError:
3280 main.log.exception( self.name + ": Object not as expected" )
3281 return None
3282 except pexpect.EOF:
3283 main.log.error( self.name + ": EOF exception found" )
3284 main.log.error( self.name + ": " + self.handle.before )
3285 main.cleanup()
3286 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003287 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003288 main.log.exception( self.name + ": Uncaught exception!" )
3289 main.cleanup()
3290 main.exit()
3291
Jon Hall146f1522015-03-24 15:33:24 -07003292 def appStatus( self, appName ):
3293 """
3294 Uses the onos:apps cli command to return the status of an application.
3295 Returns:
3296 "ACTIVE" - If app is installed and activated
3297 "INSTALLED" - If app is installed and deactivated
3298 "UNINSTALLED" - If app is not installed
3299 None - on error
3300 """
Jon Hall146f1522015-03-24 15:33:24 -07003301 try:
3302 if not isinstance( appName, types.StringType ):
3303 main.log.error( self.name + ".appStatus(): appName must be" +
3304 " a string" )
3305 return None
3306 output = self.apps( jsonFormat=True )
3307 appsJson = json.loads( output )
3308 state = None
3309 for app in appsJson:
3310 if appName == app.get('name'):
3311 state = app.get('state')
3312 break
3313 if state == "ACTIVE" or state == "INSTALLED":
3314 return state
3315 elif state is None:
3316 return "UNINSTALLED"
3317 elif state:
3318 main.log.error( "Unexpected state from 'onos:apps': " +
3319 str( state ) )
3320 return state
Jon Hallc6793552016-01-19 14:18:37 -08003321 except ( TypeError, ValueError ):
3322 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003323 return None
3324 except pexpect.EOF:
3325 main.log.error( self.name + ": EOF exception found" )
3326 main.log.error( self.name + ": " + self.handle.before )
3327 main.cleanup()
3328 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003329 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003330 main.log.exception( self.name + ": Uncaught exception!" )
3331 main.cleanup()
3332 main.exit()
3333
Jon Hallbe379602015-03-24 13:39:32 -07003334 def app( self, appName, option ):
3335 """
3336 Interacts with the app command for ONOS. This command manages
3337 application inventory.
3338 """
Jon Hallbe379602015-03-24 13:39:32 -07003339 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003340 # Validate argument types
3341 valid = True
3342 if not isinstance( appName, types.StringType ):
3343 main.log.error( self.name + ".app(): appName must be a " +
3344 "string" )
3345 valid = False
3346 if not isinstance( option, types.StringType ):
3347 main.log.error( self.name + ".app(): option must be a string" )
3348 valid = False
3349 if not valid:
3350 return main.FALSE
3351 # Validate Option
3352 option = option.lower()
3353 # NOTE: Install may become a valid option
3354 if option == "activate":
3355 pass
3356 elif option == "deactivate":
3357 pass
3358 elif option == "uninstall":
3359 pass
3360 else:
3361 # Invalid option
3362 main.log.error( "The ONOS app command argument only takes " +
3363 "the values: (activate|deactivate|uninstall)" +
3364 "; was given '" + option + "'")
3365 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003366 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003367 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003368 if "Error executing command" in output:
3369 main.log.error( "Error in processing onos:app command: " +
3370 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003371 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003372 elif "No such application" in output:
3373 main.log.error( "The application '" + appName +
3374 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003375 return main.FALSE
3376 elif "Command not found:" in output:
3377 main.log.error( "Error in processing onos:app command: " +
3378 str( output ) )
3379 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003380 elif "Unsupported command:" in output:
3381 main.log.error( "Incorrect command given to 'app': " +
3382 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003383 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003384 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003385 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003386 return main.TRUE
3387 except TypeError:
3388 main.log.exception( self.name + ": Object not as expected" )
3389 return main.ERROR
3390 except pexpect.EOF:
3391 main.log.error( self.name + ": EOF exception found" )
3392 main.log.error( self.name + ": " + self.handle.before )
3393 main.cleanup()
3394 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003395 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003396 main.log.exception( self.name + ": Uncaught exception!" )
3397 main.cleanup()
3398 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003399
Jon Hallbd16b922015-03-26 17:53:15 -07003400 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003401 """
3402 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003403 appName is the hierarchical app name, not the feature name
3404 If check is True, method will check the status of the app after the
3405 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003406 Returns main.TRUE if the command was successfully sent
3407 main.FALSE if the cli responded with an error or given
3408 incorrect input
3409 """
3410 try:
3411 if not isinstance( appName, types.StringType ):
3412 main.log.error( self.name + ".activateApp(): appName must be" +
3413 " a string" )
3414 return main.FALSE
3415 status = self.appStatus( appName )
3416 if status == "INSTALLED":
3417 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003418 if check and response == main.TRUE:
3419 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003420 status = self.appStatus( appName )
3421 if status == "ACTIVE":
3422 return main.TRUE
3423 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003424 main.log.debug( "The state of application " +
3425 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003426 time.sleep( 1 )
3427 return main.FALSE
3428 else: # not 'check' or command didn't succeed
3429 return response
Jon Hall146f1522015-03-24 15:33:24 -07003430 elif status == "ACTIVE":
3431 return main.TRUE
3432 elif status == "UNINSTALLED":
3433 main.log.error( self.name + ": Tried to activate the " +
3434 "application '" + appName + "' which is not " +
3435 "installed." )
3436 else:
3437 main.log.error( "Unexpected return value from appStatus: " +
3438 str( status ) )
3439 return main.ERROR
3440 except TypeError:
3441 main.log.exception( self.name + ": Object not as expected" )
3442 return main.ERROR
3443 except pexpect.EOF:
3444 main.log.error( self.name + ": EOF exception found" )
3445 main.log.error( self.name + ": " + self.handle.before )
3446 main.cleanup()
3447 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003448 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003449 main.log.exception( self.name + ": Uncaught exception!" )
3450 main.cleanup()
3451 main.exit()
3452
Jon Hallbd16b922015-03-26 17:53:15 -07003453 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003454 """
3455 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003456 appName is the hierarchical app name, not the feature name
3457 If check is True, method will check the status of the app after the
3458 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003459 Returns main.TRUE if the command was successfully sent
3460 main.FALSE if the cli responded with an error or given
3461 incorrect input
3462 """
3463 try:
3464 if not isinstance( appName, types.StringType ):
3465 main.log.error( self.name + ".deactivateApp(): appName must " +
3466 "be a string" )
3467 return main.FALSE
3468 status = self.appStatus( appName )
3469 if status == "INSTALLED":
3470 return main.TRUE
3471 elif status == "ACTIVE":
3472 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003473 if check and response == main.TRUE:
3474 for i in range(10): # try 10 times then give up
3475 status = self.appStatus( appName )
3476 if status == "INSTALLED":
3477 return main.TRUE
3478 else:
3479 time.sleep( 1 )
3480 return main.FALSE
3481 else: # not check or command didn't succeed
3482 return response
Jon Hall146f1522015-03-24 15:33:24 -07003483 elif status == "UNINSTALLED":
3484 main.log.warn( self.name + ": Tried to deactivate the " +
3485 "application '" + appName + "' which is not " +
3486 "installed." )
3487 return main.TRUE
3488 else:
3489 main.log.error( "Unexpected return value from appStatus: " +
3490 str( status ) )
3491 return main.ERROR
3492 except TypeError:
3493 main.log.exception( self.name + ": Object not as expected" )
3494 return main.ERROR
3495 except pexpect.EOF:
3496 main.log.error( self.name + ": EOF exception found" )
3497 main.log.error( self.name + ": " + self.handle.before )
3498 main.cleanup()
3499 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003500 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003501 main.log.exception( self.name + ": Uncaught exception!" )
3502 main.cleanup()
3503 main.exit()
3504
Jon Hallbd16b922015-03-26 17:53:15 -07003505 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003506 """
3507 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003508 appName is the hierarchical app name, not the feature name
3509 If check is True, method will check the status of the app after the
3510 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003511 Returns main.TRUE if the command was successfully sent
3512 main.FALSE if the cli responded with an error or given
3513 incorrect input
3514 """
3515 # TODO: check with Thomas about the state machine for apps
3516 try:
3517 if not isinstance( appName, types.StringType ):
3518 main.log.error( self.name + ".uninstallApp(): appName must " +
3519 "be a string" )
3520 return main.FALSE
3521 status = self.appStatus( appName )
3522 if status == "INSTALLED":
3523 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003524 if check and response == main.TRUE:
3525 for i in range(10): # try 10 times then give up
3526 status = self.appStatus( appName )
3527 if status == "UNINSTALLED":
3528 return main.TRUE
3529 else:
3530 time.sleep( 1 )
3531 return main.FALSE
3532 else: # not check or command didn't succeed
3533 return response
Jon Hall146f1522015-03-24 15:33:24 -07003534 elif status == "ACTIVE":
3535 main.log.warn( self.name + ": Tried to uninstall the " +
3536 "application '" + appName + "' which is " +
3537 "currently active." )
3538 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003539 if check and response == main.TRUE:
3540 for i in range(10): # try 10 times then give up
3541 status = self.appStatus( appName )
3542 if status == "UNINSTALLED":
3543 return main.TRUE
3544 else:
3545 time.sleep( 1 )
3546 return main.FALSE
3547 else: # not check or command didn't succeed
3548 return response
Jon Hall146f1522015-03-24 15:33:24 -07003549 elif status == "UNINSTALLED":
3550 return main.TRUE
3551 else:
3552 main.log.error( "Unexpected return value from appStatus: " +
3553 str( status ) )
3554 return main.ERROR
3555 except TypeError:
3556 main.log.exception( self.name + ": Object not as expected" )
3557 return main.ERROR
3558 except pexpect.EOF:
3559 main.log.error( self.name + ": EOF exception found" )
3560 main.log.error( self.name + ": " + self.handle.before )
3561 main.cleanup()
3562 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003563 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003564 main.log.exception( self.name + ": Uncaught exception!" )
3565 main.cleanup()
3566 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003567
3568 def appIDs( self, jsonFormat=True ):
3569 """
3570 Show the mappings between app id and app names given by the 'app-ids'
3571 cli command
3572 """
3573 try:
3574 cmdStr = "app-ids"
3575 if jsonFormat:
3576 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003577 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003578 assert "Command not found:" not in output, output
3579 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003580 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003581 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003582 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003583 return None
3584 except TypeError:
3585 main.log.exception( self.name + ": Object not as expected" )
3586 return None
3587 except pexpect.EOF:
3588 main.log.error( self.name + ": EOF exception found" )
3589 main.log.error( self.name + ": " + self.handle.before )
3590 main.cleanup()
3591 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003592 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003593 main.log.exception( self.name + ": Uncaught exception!" )
3594 main.cleanup()
3595 main.exit()
3596
3597 def appToIDCheck( self ):
3598 """
3599 This method will check that each application's ID listed in 'apps' is
3600 the same as the ID listed in 'app-ids'. The check will also check that
3601 there are no duplicate IDs issued. Note that an app ID should be
3602 a globaly unique numerical identifier for app/app-like features. Once
3603 an ID is registered, the ID is never freed up so that if an app is
3604 reinstalled it will have the same ID.
3605
3606 Returns: main.TRUE if the check passes and
3607 main.FALSE if the check fails or
3608 main.ERROR if there is some error in processing the test
3609 """
3610 try:
Jon Hall390696c2015-05-05 17:13:41 -07003611 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003612 rawJson = self.appIDs( jsonFormat=True )
3613 if rawJson:
3614 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003615 else:
Jon Hallc6793552016-01-19 14:18:37 -08003616 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003617 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003618 rawJson = self.apps( jsonFormat=True )
3619 if rawJson:
3620 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003621 else:
Jon Hallc6793552016-01-19 14:18:37 -08003622 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003623 bail = True
3624 if bail:
3625 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003626 result = main.TRUE
3627 for app in apps:
3628 appID = app.get( 'id' )
3629 if appID is None:
3630 main.log.error( "Error parsing app: " + str( app ) )
3631 result = main.FALSE
3632 appName = app.get( 'name' )
3633 if appName is None:
3634 main.log.error( "Error parsing app: " + str( app ) )
3635 result = main.FALSE
3636 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003637 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003638 # main.log.debug( "Comparing " + str( app ) + " to " +
3639 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003640 if not current: # if ids doesn't have this id
3641 result = main.FALSE
3642 main.log.error( "'app-ids' does not have the ID for " +
3643 str( appName ) + " that apps does." )
3644 elif len( current ) > 1:
3645 # there is more than one app with this ID
3646 result = main.FALSE
3647 # We will log this later in the method
3648 elif not current[0][ 'name' ] == appName:
3649 currentName = current[0][ 'name' ]
3650 result = main.FALSE
3651 main.log.error( "'app-ids' has " + str( currentName ) +
3652 " registered under id:" + str( appID ) +
3653 " but 'apps' has " + str( appName ) )
3654 else:
3655 pass # id and name match!
3656 # now make sure that app-ids has no duplicates
3657 idsList = []
3658 namesList = []
3659 for item in ids:
3660 idsList.append( item[ 'id' ] )
3661 namesList.append( item[ 'name' ] )
3662 if len( idsList ) != len( set( idsList ) ) or\
3663 len( namesList ) != len( set( namesList ) ):
3664 main.log.error( "'app-ids' has some duplicate entries: \n"
3665 + json.dumps( ids,
3666 sort_keys=True,
3667 indent=4,
3668 separators=( ',', ': ' ) ) )
3669 result = main.FALSE
3670 return result
Jon Hallc6793552016-01-19 14:18:37 -08003671 except ( TypeError, ValueError ):
3672 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003673 return main.ERROR
3674 except pexpect.EOF:
3675 main.log.error( self.name + ": EOF exception found" )
3676 main.log.error( self.name + ": " + self.handle.before )
3677 main.cleanup()
3678 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003679 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003680 main.log.exception( self.name + ": Uncaught exception!" )
3681 main.cleanup()
3682 main.exit()
3683
Jon Hallfb760a02015-04-13 15:35:03 -07003684 def getCfg( self, component=None, propName=None, short=False,
3685 jsonFormat=True ):
3686 """
3687 Get configuration settings from onos cli
3688 Optional arguments:
3689 component - Optionally only list configurations for a specific
3690 component. If None, all components with configurations
3691 are displayed. Case Sensitive string.
3692 propName - If component is specified, propName option will show
3693 only this specific configuration from that component.
3694 Case Sensitive string.
3695 jsonFormat - Returns output as json. Note that this will override
3696 the short option
3697 short - Short, less verbose, version of configurations.
3698 This is overridden by the json option
3699 returns:
3700 Output from cli as a string or None on error
3701 """
3702 try:
3703 baseStr = "cfg"
3704 cmdStr = " get"
3705 componentStr = ""
3706 if component:
3707 componentStr += " " + component
3708 if propName:
3709 componentStr += " " + propName
3710 if jsonFormat:
3711 baseStr += " -j"
3712 elif short:
3713 baseStr += " -s"
3714 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
3716 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003717 return output
3718 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003719 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003720 return None
3721 except TypeError:
3722 main.log.exception( self.name + ": Object not as expected" )
3723 return None
3724 except pexpect.EOF:
3725 main.log.error( self.name + ": EOF exception found" )
3726 main.log.error( self.name + ": " + self.handle.before )
3727 main.cleanup()
3728 main.exit()
3729 except Exception:
3730 main.log.exception( self.name + ": Uncaught exception!" )
3731 main.cleanup()
3732 main.exit()
3733
3734 def setCfg( self, component, propName, value=None, check=True ):
3735 """
3736 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003737 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003738 component - The case sensitive name of the component whose
3739 property is to be set
3740 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003741 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003742 value - The value to set the property to. If None, will unset the
3743 property and revert it to it's default value(if applicable)
3744 check - Boolean, Check whether the option was successfully set this
3745 only applies when a value is given.
3746 returns:
3747 main.TRUE on success or main.FALSE on failure. If check is False,
3748 will return main.TRUE unless there is an error
3749 """
3750 try:
3751 baseStr = "cfg"
3752 cmdStr = " set " + str( component ) + " " + str( propName )
3753 if value is not None:
3754 cmdStr += " " + str( value )
3755 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003756 assert "Command not found:" not in output, output
3757 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003758 if value and check:
3759 results = self.getCfg( component=str( component ),
3760 propName=str( propName ),
3761 jsonFormat=True )
3762 # Check if current value is what we just set
3763 try:
3764 jsonOutput = json.loads( results )
3765 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003766 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003767 main.log.exception( "Error parsing cfg output" )
3768 main.log.error( "output:" + repr( results ) )
3769 return main.FALSE
3770 if current == str( value ):
3771 return main.TRUE
3772 return main.FALSE
3773 return main.TRUE
3774 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003775 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003776 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003777 except ( TypeError, ValueError ):
3778 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003779 return main.FALSE
3780 except pexpect.EOF:
3781 main.log.error( self.name + ": EOF exception found" )
3782 main.log.error( self.name + ": " + self.handle.before )
3783 main.cleanup()
3784 main.exit()
3785 except Exception:
3786 main.log.exception( self.name + ": Uncaught exception!" )
3787 main.cleanup()
3788 main.exit()
3789
Jon Hall390696c2015-05-05 17:13:41 -07003790 def setTestAdd( self, setName, values ):
3791 """
3792 CLI command to add elements to a distributed set.
3793 Arguments:
3794 setName - The name of the set to add to.
3795 values - The value(s) to add to the set, space seperated.
3796 Example usages:
3797 setTestAdd( "set1", "a b c" )
3798 setTestAdd( "set2", "1" )
3799 returns:
3800 main.TRUE on success OR
3801 main.FALSE if elements were already in the set OR
3802 main.ERROR on error
3803 """
3804 try:
3805 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3806 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003807 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003808 try:
3809 # TODO: Maybe make this less hardcoded
3810 # ConsistentMap Exceptions
3811 assert "org.onosproject.store.service" not in output
3812 # Node not leader
3813 assert "java.lang.IllegalStateException" not in output
3814 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003815 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003816 "command: " + str( output ) )
3817 retryTime = 30 # Conservative time, given by Madan
3818 main.log.info( "Waiting " + str( retryTime ) +
3819 "seconds before retrying." )
3820 time.sleep( retryTime ) # Due to change in mastership
3821 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003822 assert "Error executing command" not in output
3823 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3824 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3825 main.log.info( self.name + ": " + output )
3826 if re.search( positiveMatch, output):
3827 return main.TRUE
3828 elif re.search( negativeMatch, output):
3829 return main.FALSE
3830 else:
3831 main.log.error( self.name + ": setTestAdd did not" +
3832 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003833 main.log.debug( self.name + " actual: " + repr( output ) )
3834 return main.ERROR
3835 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003836 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003837 return main.ERROR
3838 except TypeError:
3839 main.log.exception( self.name + ": Object not as expected" )
3840 return main.ERROR
3841 except pexpect.EOF:
3842 main.log.error( self.name + ": EOF exception found" )
3843 main.log.error( self.name + ": " + self.handle.before )
3844 main.cleanup()
3845 main.exit()
3846 except Exception:
3847 main.log.exception( self.name + ": Uncaught exception!" )
3848 main.cleanup()
3849 main.exit()
3850
3851 def setTestRemove( self, setName, values, clear=False, retain=False ):
3852 """
3853 CLI command to remove elements from a distributed set.
3854 Required arguments:
3855 setName - The name of the set to remove from.
3856 values - The value(s) to remove from the set, space seperated.
3857 Optional arguments:
3858 clear - Clear all elements from the set
3859 retain - Retain only the given values. (intersection of the
3860 original set and the given set)
3861 returns:
3862 main.TRUE on success OR
3863 main.FALSE if the set was not changed OR
3864 main.ERROR on error
3865 """
3866 try:
3867 cmdStr = "set-test-remove "
3868 if clear:
3869 cmdStr += "-c " + str( setName )
3870 elif retain:
3871 cmdStr += "-r " + str( setName ) + " " + str( values )
3872 else:
3873 cmdStr += str( setName ) + " " + str( values )
3874 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003875 try:
3876 # TODO: Maybe make this less hardcoded
3877 # ConsistentMap Exceptions
3878 assert "org.onosproject.store.service" not in output
3879 # Node not leader
3880 assert "java.lang.IllegalStateException" not in output
3881 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003882 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003883 "command: " + str( output ) )
3884 retryTime = 30 # Conservative time, given by Madan
3885 main.log.info( "Waiting " + str( retryTime ) +
3886 "seconds before retrying." )
3887 time.sleep( retryTime ) # Due to change in mastership
3888 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003889 assert "Command not found:" not in output, output
3890 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003891 main.log.info( self.name + ": " + output )
3892 if clear:
3893 pattern = "Set " + str( setName ) + " cleared"
3894 if re.search( pattern, output ):
3895 return main.TRUE
3896 elif retain:
3897 positivePattern = str( setName ) + " was pruned to contain " +\
3898 "only elements of set \[(.*)\]"
3899 negativePattern = str( setName ) + " was not changed by " +\
3900 "retaining only elements of the set " +\
3901 "\[(.*)\]"
3902 if re.search( positivePattern, output ):
3903 return main.TRUE
3904 elif re.search( negativePattern, output ):
3905 return main.FALSE
3906 else:
3907 positivePattern = "\[(.*)\] was removed from the set " +\
3908 str( setName )
3909 if ( len( values.split() ) == 1 ):
3910 negativePattern = "\[(.*)\] was not in set " +\
3911 str( setName )
3912 else:
3913 negativePattern = "No element of \[(.*)\] was in set " +\
3914 str( setName )
3915 if re.search( positivePattern, output ):
3916 return main.TRUE
3917 elif re.search( negativePattern, output ):
3918 return main.FALSE
3919 main.log.error( self.name + ": setTestRemove did not" +
3920 " match expected output" )
3921 main.log.debug( self.name + " expected: " + pattern )
3922 main.log.debug( self.name + " actual: " + repr( output ) )
3923 return main.ERROR
3924 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003925 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003926 return main.ERROR
3927 except TypeError:
3928 main.log.exception( self.name + ": Object not as expected" )
3929 return main.ERROR
3930 except pexpect.EOF:
3931 main.log.error( self.name + ": EOF exception found" )
3932 main.log.error( self.name + ": " + self.handle.before )
3933 main.cleanup()
3934 main.exit()
3935 except Exception:
3936 main.log.exception( self.name + ": Uncaught exception!" )
3937 main.cleanup()
3938 main.exit()
3939
3940 def setTestGet( self, setName, values="" ):
3941 """
3942 CLI command to get the elements in a distributed set.
3943 Required arguments:
3944 setName - The name of the set to remove from.
3945 Optional arguments:
3946 values - The value(s) to check if in the set, space seperated.
3947 returns:
3948 main.ERROR on error OR
3949 A list of elements in the set if no optional arguments are
3950 supplied OR
3951 A tuple containing the list then:
3952 main.FALSE if the given values are not in the set OR
3953 main.TRUE if the given values are in the set OR
3954 """
3955 try:
3956 values = str( values ).strip()
3957 setName = str( setName ).strip()
3958 length = len( values.split() )
3959 containsCheck = None
3960 # Patterns to match
3961 setPattern = "\[(.*)\]"
3962 pattern = "Items in set " + setName + ":\n" + setPattern
3963 containsTrue = "Set " + setName + " contains the value " + values
3964 containsFalse = "Set " + setName + " did not contain the value " +\
3965 values
3966 containsAllTrue = "Set " + setName + " contains the the subset " +\
3967 setPattern
3968 containsAllFalse = "Set " + setName + " did not contain the the" +\
3969 " subset " + setPattern
3970
3971 cmdStr = "set-test-get "
3972 cmdStr += setName + " " + values
3973 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003974 try:
3975 # TODO: Maybe make this less hardcoded
3976 # ConsistentMap Exceptions
3977 assert "org.onosproject.store.service" not in output
3978 # Node not leader
3979 assert "java.lang.IllegalStateException" not in output
3980 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003981 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003982 "command: " + str( output ) )
3983 retryTime = 30 # Conservative time, given by Madan
3984 main.log.info( "Waiting " + str( retryTime ) +
3985 "seconds before retrying." )
3986 time.sleep( retryTime ) # Due to change in mastership
3987 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003988 assert "Command not found:" not in output, output
3989 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003990 main.log.info( self.name + ": " + output )
3991
3992 if length == 0:
3993 match = re.search( pattern, output )
3994 else: # if given values
3995 if length == 1: # Contains output
3996 patternTrue = pattern + "\n" + containsTrue
3997 patternFalse = pattern + "\n" + containsFalse
3998 else: # ContainsAll output
3999 patternTrue = pattern + "\n" + containsAllTrue
4000 patternFalse = pattern + "\n" + containsAllFalse
4001 matchTrue = re.search( patternTrue, output )
4002 matchFalse = re.search( patternFalse, output )
4003 if matchTrue:
4004 containsCheck = main.TRUE
4005 match = matchTrue
4006 elif matchFalse:
4007 containsCheck = main.FALSE
4008 match = matchFalse
4009 else:
4010 main.log.error( self.name + " setTestGet did not match " +\
4011 "expected output" )
4012 main.log.debug( self.name + " expected: " + pattern )
4013 main.log.debug( self.name + " actual: " + repr( output ) )
4014 match = None
4015 if match:
4016 setMatch = match.group( 1 )
4017 if setMatch == '':
4018 setList = []
4019 else:
4020 setList = setMatch.split( ", " )
4021 if length > 0:
4022 return ( setList, containsCheck )
4023 else:
4024 return setList
4025 else: # no match
4026 main.log.error( self.name + ": setTestGet did not" +
4027 " match expected output" )
4028 main.log.debug( self.name + " expected: " + pattern )
4029 main.log.debug( self.name + " actual: " + repr( output ) )
4030 return main.ERROR
4031 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004032 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004033 return main.ERROR
4034 except TypeError:
4035 main.log.exception( self.name + ": Object not as expected" )
4036 return main.ERROR
4037 except pexpect.EOF:
4038 main.log.error( self.name + ": EOF exception found" )
4039 main.log.error( self.name + ": " + self.handle.before )
4040 main.cleanup()
4041 main.exit()
4042 except Exception:
4043 main.log.exception( self.name + ": Uncaught exception!" )
4044 main.cleanup()
4045 main.exit()
4046
4047 def setTestSize( self, setName ):
4048 """
4049 CLI command to get the elements in a distributed set.
4050 Required arguments:
4051 setName - The name of the set to remove from.
4052 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004053 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004054 None on error
4055 """
4056 try:
4057 # TODO: Should this check against the number of elements returned
4058 # and then return true/false based on that?
4059 setName = str( setName ).strip()
4060 # Patterns to match
4061 setPattern = "\[(.*)\]"
4062 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4063 setPattern
4064 cmdStr = "set-test-get -s "
4065 cmdStr += setName
4066 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004067 try:
4068 # TODO: Maybe make this less hardcoded
4069 # ConsistentMap Exceptions
4070 assert "org.onosproject.store.service" not in output
4071 # Node not leader
4072 assert "java.lang.IllegalStateException" not in output
4073 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004074 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004075 "command: " + str( output ) )
4076 retryTime = 30 # Conservative time, given by Madan
4077 main.log.info( "Waiting " + str( retryTime ) +
4078 "seconds before retrying." )
4079 time.sleep( retryTime ) # Due to change in mastership
4080 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004081 assert "Command not found:" not in output, output
4082 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004083 main.log.info( self.name + ": " + output )
4084 match = re.search( pattern, output )
4085 if match:
4086 setSize = int( match.group( 1 ) )
4087 setMatch = match.group( 2 )
4088 if len( setMatch.split() ) == setSize:
4089 main.log.info( "The size returned by " + self.name +
4090 " matches the number of elements in " +
4091 "the returned set" )
4092 else:
4093 main.log.error( "The size returned by " + self.name +
4094 " does not match the number of " +
4095 "elements in the returned set." )
4096 return setSize
4097 else: # no match
4098 main.log.error( self.name + ": setTestGet did not" +
4099 " match expected output" )
4100 main.log.debug( self.name + " expected: " + pattern )
4101 main.log.debug( self.name + " actual: " + repr( output ) )
4102 return None
4103 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004104 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004105 return None
Jon Hall390696c2015-05-05 17:13:41 -07004106 except TypeError:
4107 main.log.exception( self.name + ": Object not as expected" )
4108 return None
4109 except pexpect.EOF:
4110 main.log.error( self.name + ": EOF exception found" )
4111 main.log.error( self.name + ": " + self.handle.before )
4112 main.cleanup()
4113 main.exit()
4114 except Exception:
4115 main.log.exception( self.name + ": Uncaught exception!" )
4116 main.cleanup()
4117 main.exit()
4118
Jon Hall80daded2015-05-27 16:07:00 -07004119 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004120 """
4121 Command to list the various counters in the system.
4122 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004123 if jsonFormat, a string of the json object returned by the cli
4124 command
4125 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004126 None on error
4127 """
Jon Hall390696c2015-05-05 17:13:41 -07004128 try:
4129 counters = {}
4130 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004131 if jsonFormat:
4132 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004133 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004134 assert "Command not found:" not in output, output
4135 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004136 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004137 return output
Jon Hall390696c2015-05-05 17:13:41 -07004138 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004139 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004140 return None
Jon Hall390696c2015-05-05 17:13:41 -07004141 except TypeError:
4142 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004143 return None
Jon Hall390696c2015-05-05 17:13:41 -07004144 except pexpect.EOF:
4145 main.log.error( self.name + ": EOF exception found" )
4146 main.log.error( self.name + ": " + self.handle.before )
4147 main.cleanup()
4148 main.exit()
4149 except Exception:
4150 main.log.exception( self.name + ": Uncaught exception!" )
4151 main.cleanup()
4152 main.exit()
4153
Jon Hall935db192016-04-19 00:22:04 -07004154 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004155 """
Jon Halle1a3b752015-07-22 13:02:46 -07004156 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004157 Required arguments:
4158 counter - The name of the counter to increment.
4159 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004160 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004161 returns:
4162 integer value of the counter or
4163 None on Error
4164 """
4165 try:
4166 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004167 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004168 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004169 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004170 if delta != 1:
4171 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004172 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004173 try:
4174 # TODO: Maybe make this less hardcoded
4175 # ConsistentMap Exceptions
4176 assert "org.onosproject.store.service" not in output
4177 # Node not leader
4178 assert "java.lang.IllegalStateException" not in output
4179 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004180 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004181 "command: " + str( output ) )
4182 retryTime = 30 # Conservative time, given by Madan
4183 main.log.info( "Waiting " + str( retryTime ) +
4184 "seconds before retrying." )
4185 time.sleep( retryTime ) # Due to change in mastership
4186 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004187 assert "Command not found:" not in output, output
4188 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004189 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004190 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004191 match = re.search( pattern, output )
4192 if match:
4193 return int( match.group( 1 ) )
4194 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004195 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004196 " match expected output." )
4197 main.log.debug( self.name + " expected: " + pattern )
4198 main.log.debug( self.name + " actual: " + repr( output ) )
4199 return None
4200 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004201 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004202 return None
4203 except TypeError:
4204 main.log.exception( self.name + ": Object not as expected" )
4205 return None
4206 except pexpect.EOF:
4207 main.log.error( self.name + ": EOF exception found" )
4208 main.log.error( self.name + ": " + self.handle.before )
4209 main.cleanup()
4210 main.exit()
4211 except Exception:
4212 main.log.exception( self.name + ": Uncaught exception!" )
4213 main.cleanup()
4214 main.exit()
4215
Jon Hall935db192016-04-19 00:22:04 -07004216 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004217 """
4218 CLI command to get a distributed counter then add a delta to it.
4219 Required arguments:
4220 counter - The name of the counter to increment.
4221 Optional arguments:
4222 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004223 returns:
4224 integer value of the counter or
4225 None on Error
4226 """
4227 try:
4228 counter = str( counter )
4229 delta = int( delta )
4230 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004231 cmdStr += counter
4232 if delta != 1:
4233 cmdStr += " " + str( delta )
4234 output = self.sendline( cmdStr )
4235 try:
4236 # TODO: Maybe make this less hardcoded
4237 # ConsistentMap Exceptions
4238 assert "org.onosproject.store.service" not in output
4239 # Node not leader
4240 assert "java.lang.IllegalStateException" not in output
4241 except AssertionError:
4242 main.log.error( "Error in processing '" + cmdStr + "' " +
4243 "command: " + str( output ) )
4244 retryTime = 30 # Conservative time, given by Madan
4245 main.log.info( "Waiting " + str( retryTime ) +
4246 "seconds before retrying." )
4247 time.sleep( retryTime ) # Due to change in mastership
4248 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004249 assert "Command not found:" not in output, output
4250 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004251 main.log.info( self.name + ": " + output )
4252 pattern = counter + " was updated to (-?\d+)"
4253 match = re.search( pattern, output )
4254 if match:
4255 return int( match.group( 1 ) )
4256 else:
4257 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4258 " match expected output." )
4259 main.log.debug( self.name + " expected: " + pattern )
4260 main.log.debug( self.name + " actual: " + repr( output ) )
4261 return None
4262 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004263 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004264 return None
4265 except TypeError:
4266 main.log.exception( self.name + ": Object not as expected" )
4267 return None
4268 except pexpect.EOF:
4269 main.log.error( self.name + ": EOF exception found" )
4270 main.log.error( self.name + ": " + self.handle.before )
4271 main.cleanup()
4272 main.exit()
4273 except Exception:
4274 main.log.exception( self.name + ": Uncaught exception!" )
4275 main.cleanup()
4276 main.exit()
4277
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004278 def summary( self, jsonFormat=True ):
4279 """
4280 Description: Execute summary command in onos
4281 Returns: json object ( summary -j ), returns main.FALSE if there is
4282 no output
4283
4284 """
4285 try:
4286 cmdStr = "summary"
4287 if jsonFormat:
4288 cmdStr += " -j"
4289 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004290 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004291 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004292 if not handle:
4293 main.log.error( self.name + ": There is no output in " +
4294 "summary command" )
4295 return main.FALSE
4296 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004297 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004298 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004299 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004300 except TypeError:
4301 main.log.exception( self.name + ": Object not as expected" )
4302 return None
4303 except pexpect.EOF:
4304 main.log.error( self.name + ": EOF exception found" )
4305 main.log.error( self.name + ": " + self.handle.before )
4306 main.cleanup()
4307 main.exit()
4308 except Exception:
4309 main.log.exception( self.name + ": Uncaught exception!" )
4310 main.cleanup()
4311 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004312
Jon Hall935db192016-04-19 00:22:04 -07004313 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004314 """
4315 CLI command to get the value of a key in a consistent map using
4316 transactions. This a test function and can only get keys from the
4317 test map hard coded into the cli command
4318 Required arguments:
4319 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004320 returns:
4321 The string value of the key or
4322 None on Error
4323 """
4324 try:
4325 keyName = str( keyName )
4326 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004327 cmdStr += keyName
4328 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004329 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004330 try:
4331 # TODO: Maybe make this less hardcoded
4332 # ConsistentMap Exceptions
4333 assert "org.onosproject.store.service" not in output
4334 # Node not leader
4335 assert "java.lang.IllegalStateException" not in output
4336 except AssertionError:
4337 main.log.error( "Error in processing '" + cmdStr + "' " +
4338 "command: " + str( output ) )
4339 return None
4340 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4341 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004342 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004343 return None
4344 else:
4345 match = re.search( pattern, output )
4346 if match:
4347 return match.groupdict()[ 'value' ]
4348 else:
4349 main.log.error( self.name + ": transactionlMapGet did not" +
4350 " match expected output." )
4351 main.log.debug( self.name + " expected: " + pattern )
4352 main.log.debug( self.name + " actual: " + repr( output ) )
4353 return None
Jon Hallc6793552016-01-19 14:18:37 -08004354 except AssertionError:
4355 main.log.exception( "" )
4356 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004357 except TypeError:
4358 main.log.exception( self.name + ": Object not as expected" )
4359 return None
4360 except pexpect.EOF:
4361 main.log.error( self.name + ": EOF exception found" )
4362 main.log.error( self.name + ": " + self.handle.before )
4363 main.cleanup()
4364 main.exit()
4365 except Exception:
4366 main.log.exception( self.name + ": Uncaught exception!" )
4367 main.cleanup()
4368 main.exit()
4369
Jon Hall935db192016-04-19 00:22:04 -07004370 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004371 """
4372 CLI command to put a value into 'numKeys' number of keys in a
4373 consistent map using transactions. This a test function and can only
4374 put into keys named 'Key#' of the test map hard coded into the cli command
4375 Required arguments:
4376 numKeys - Number of keys to add the value to
4377 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004378 returns:
4379 A dictionary whose keys are the name of the keys put into the map
4380 and the values of the keys are dictionaries whose key-values are
4381 'value': value put into map and optionaly
4382 'oldValue': Previous value in the key or
4383 None on Error
4384
4385 Example output
4386 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4387 'Key2': {'value': 'Testing'} }
4388 """
4389 try:
4390 numKeys = str( numKeys )
4391 value = str( value )
4392 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004393 cmdStr += numKeys + " " + value
4394 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004395 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004396 try:
4397 # TODO: Maybe make this less hardcoded
4398 # ConsistentMap Exceptions
4399 assert "org.onosproject.store.service" not in output
4400 # Node not leader
4401 assert "java.lang.IllegalStateException" not in output
4402 except AssertionError:
4403 main.log.error( "Error in processing '" + cmdStr + "' " +
4404 "command: " + str( output ) )
4405 return None
4406 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4407 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4408 results = {}
4409 for line in output.splitlines():
4410 new = re.search( newPattern, line )
4411 updated = re.search( updatedPattern, line )
4412 if new:
4413 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4414 elif updated:
4415 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004416 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004417 else:
4418 main.log.error( self.name + ": transactionlMapGet did not" +
4419 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004420 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4421 newPattern,
4422 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004423 main.log.debug( self.name + " actual: " + repr( output ) )
4424 return results
Jon Hallc6793552016-01-19 14:18:37 -08004425 except AssertionError:
4426 main.log.exception( "" )
4427 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004428 except TypeError:
4429 main.log.exception( self.name + ": Object not as expected" )
4430 return None
4431 except pexpect.EOF:
4432 main.log.error( self.name + ": EOF exception found" )
4433 main.log.error( self.name + ": " + self.handle.before )
4434 main.cleanup()
4435 main.exit()
4436 except Exception:
4437 main.log.exception( self.name + ": Uncaught exception!" )
4438 main.cleanup()
4439 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004440
acsmarsdaea66c2015-09-03 11:44:06 -07004441 def maps( self, jsonFormat=True ):
4442 """
4443 Description: Returns result of onos:maps
4444 Optional:
4445 * jsonFormat: enable json formatting of output
4446 """
4447 try:
4448 cmdStr = "maps"
4449 if jsonFormat:
4450 cmdStr += " -j"
4451 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004452 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004453 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004454 except AssertionError:
4455 main.log.exception( "" )
4456 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004457 except TypeError:
4458 main.log.exception( self.name + ": Object not as expected" )
4459 return None
4460 except pexpect.EOF:
4461 main.log.error( self.name + ": EOF exception found" )
4462 main.log.error( self.name + ": " + self.handle.before )
4463 main.cleanup()
4464 main.exit()
4465 except Exception:
4466 main.log.exception( self.name + ": Uncaught exception!" )
4467 main.cleanup()
4468 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004469
4470 def getSwController( self, uri, jsonFormat=True ):
4471 """
4472 Descrition: Gets the controller information from the device
4473 """
4474 try:
4475 cmd = "device-controllers "
4476 if jsonFormat:
4477 cmd += "-j "
4478 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004479 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004480 return response
Jon Hallc6793552016-01-19 14:18:37 -08004481 except AssertionError:
4482 main.log.exception( "" )
4483 return None
GlennRC050596c2015-11-18 17:06:41 -08004484 except TypeError:
4485 main.log.exception( self.name + ": Object not as expected" )
4486 return None
4487 except pexpect.EOF:
4488 main.log.error( self.name + ": EOF exception found" )
4489 main.log.error( self.name + ": " + self.handle.before )
4490 main.cleanup()
4491 main.exit()
4492 except Exception:
4493 main.log.exception( self.name + ": Uncaught exception!" )
4494 main.cleanup()
4495 main.exit()
4496
4497 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4498 """
4499 Descrition: sets the controller(s) for the specified device
4500
4501 Parameters:
4502 Required: uri - String: The uri of the device(switch).
4503 ip - String or List: The ip address of the controller.
4504 This parameter can be formed in a couple of different ways.
4505 VALID:
4506 10.0.0.1 - just the ip address
4507 tcp:10.0.0.1 - the protocol and the ip address
4508 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4509 so that you can add controllers with different
4510 protocols and ports
4511 INVALID:
4512 10.0.0.1:6653 - this is not supported by ONOS
4513
4514 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4515 port - The port number.
4516 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4517
4518 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4519 """
4520 try:
4521 cmd = "device-setcontrollers"
4522
4523 if jsonFormat:
4524 cmd += " -j"
4525 cmd += " " + uri
4526 if isinstance( ip, str ):
4527 ip = [ip]
4528 for item in ip:
4529 if ":" in item:
4530 sitem = item.split( ":" )
4531 if len(sitem) == 3:
4532 cmd += " " + item
4533 elif "." in sitem[1]:
4534 cmd += " {}:{}".format(item, port)
4535 else:
4536 main.log.error( "Malformed entry: " + item )
4537 raise TypeError
4538 else:
4539 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004540 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004541 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004542 if "Error" in response:
4543 main.log.error( response )
4544 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004545 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004546 except AssertionError:
4547 main.log.exception( "" )
4548 return None
GlennRC050596c2015-11-18 17:06:41 -08004549 except TypeError:
4550 main.log.exception( self.name + ": Object not as expected" )
4551 return main.FALSE
4552 except pexpect.EOF:
4553 main.log.error( self.name + ": EOF exception found" )
4554 main.log.error( self.name + ": " + self.handle.before )
4555 main.cleanup()
4556 main.exit()
4557 except Exception:
4558 main.log.exception( self.name + ": Uncaught exception!" )
4559 main.cleanup()
4560 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004561
4562 def removeDevice( self, device ):
4563 '''
4564 Description:
4565 Remove a device from ONOS by passing the uri of the device(s).
4566 Parameters:
4567 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4568 Returns:
4569 Returns main.FALSE if an exception is thrown or an error is present
4570 in the response. Otherwise, returns main.TRUE.
4571 NOTE:
4572 If a host cannot be removed, then this function will return main.FALSE
4573 '''
4574 try:
4575 if type( device ) is str:
4576 device = list( device )
4577
4578 for d in device:
4579 time.sleep( 1 )
4580 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004581 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004582 if "Error" in response:
4583 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4584 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004585 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004586 except AssertionError:
4587 main.log.exception( "" )
4588 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004589 except TypeError:
4590 main.log.exception( self.name + ": Object not as expected" )
4591 return main.FALSE
4592 except pexpect.EOF:
4593 main.log.error( self.name + ": EOF exception found" )
4594 main.log.error( self.name + ": " + self.handle.before )
4595 main.cleanup()
4596 main.exit()
4597 except Exception:
4598 main.log.exception( self.name + ": Uncaught exception!" )
4599 main.cleanup()
4600 main.exit()
4601
4602 def removeHost( self, host ):
4603 '''
4604 Description:
4605 Remove a host from ONOS by passing the id of the host(s)
4606 Parameters:
4607 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4608 Returns:
4609 Returns main.FALSE if an exception is thrown or an error is present
4610 in the response. Otherwise, returns main.TRUE.
4611 NOTE:
4612 If a host cannot be removed, then this function will return main.FALSE
4613 '''
4614 try:
4615 if type( host ) is str:
4616 host = list( host )
4617
4618 for h in host:
4619 time.sleep( 1 )
4620 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004621 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004622 if "Error" in response:
4623 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4624 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004625 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004626 except AssertionError:
4627 main.log.exception( "" )
4628 return None
GlennRC20fc6522015-12-23 23:26:57 -08004629 except TypeError:
4630 main.log.exception( self.name + ": Object not as expected" )
4631 return main.FALSE
4632 except pexpect.EOF:
4633 main.log.error( self.name + ": EOF exception found" )
4634 main.log.error( self.name + ": " + self.handle.before )
4635 main.cleanup()
4636 main.exit()
4637 except Exception:
4638 main.log.exception( self.name + ": Uncaught exception!" )
4639 main.cleanup()
4640 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004641
Jon Hallc6793552016-01-19 14:18:37 -08004642 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004643 '''
4644 Description:
4645 Bring link down or up in the null-provider.
4646 params:
4647 begin - (string) One end of a device or switch.
4648 end - (string) the other end of the device or switch
4649 returns:
4650 main.TRUE if no exceptions were thrown and no Errors are
4651 present in the resoponse. Otherwise, returns main.FALSE
4652 '''
4653 try:
Jon Hallc6793552016-01-19 14:18:37 -08004654 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004655 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004656 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004657 if "Error" in response or "Failure" in response:
4658 main.log.error( response )
4659 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004660 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004661 except AssertionError:
4662 main.log.exception( "" )
4663 return None
GlennRCed771242016-01-13 17:02:47 -08004664 except TypeError:
4665 main.log.exception( self.name + ": Object not as expected" )
4666 return main.FALSE
4667 except pexpect.EOF:
4668 main.log.error( self.name + ": EOF exception found" )
4669 main.log.error( self.name + ": " + self.handle.before )
4670 main.cleanup()
4671 main.exit()
4672 except Exception:
4673 main.log.exception( self.name + ": Uncaught exception!" )
4674 main.cleanup()
4675 main.exit()
4676