blob: b487096fb9cdad9159d11cbc9b51b803f0c82640 [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:
kelvin-onlab338f5512015-02-06 10:53:16 -0800450 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
451 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800452 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800453 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800454 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800455 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800456 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
457 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700458 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700459 main.log.debug( self.name + ": Raw output" )
460 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700461
462 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800464 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700465 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700466 main.log.debug( self.name + ": ansiEscape output" )
467 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700468
kelvin-onlabfb521662015-02-27 09:52:40 -0800469 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800470 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700471 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.log.debug( self.name + ": Removed extra returns " +
473 "from output" )
474 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700475
476 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800477 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700478 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700479 main.log.debug( self.name + ": parsed and stripped output" )
480 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700481
Jon Hall63604932015-02-26 17:09:50 -0800482 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700483 output = response.split( cmdStr.strip(), 1 )
484 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700485 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700486 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700487 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800488 output = output[1].strip()
489 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800490 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800491 return output
GlennRCed771242016-01-13 17:02:47 -0800492 except pexpect.TIMEOUT:
493 main.log.error( self.name + ":ONOS timeout" )
494 if debug:
495 main.log.debug( self.handle.before )
496 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700497 except IndexError:
498 main.log.exception( self.name + ": Object not as expected" )
499 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800500 except TypeError:
501 main.log.exception( self.name + ": Object not as expected" )
502 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400503 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800504 main.log.error( self.name + ": EOF exception found" )
505 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400506 main.cleanup()
507 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800508 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800509 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400510 main.cleanup()
511 main.exit()
512
kelvin8ec71442015-01-15 16:57:00 -0800513 # IMPORTANT NOTE:
514 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 # the cli command changing 'a:b' with 'aB'.
516 # Ex ) onos:topology > onosTopology
517 # onos:links > onosLinks
518 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800519
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800521 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400522 Adds a new cluster node by ID and address information.
523 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800524 * nodeId
525 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400526 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800527 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800528 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400529 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800530 cmdStr = "add-node " + str( nodeId ) + " " +\
531 str( ONOSIp ) + " " + str( tcpPort )
532 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800533 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800534 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800535 main.log.error( "Error in adding node" )
536 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800537 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400540 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800541 except AssertionError:
542 main.log.exception( "" )
543 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800544 except TypeError:
545 main.log.exception( self.name + ": Object not as expected" )
546 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400547 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800548 main.log.error( self.name + ": EOF exception found" )
549 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400550 main.cleanup()
551 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800552 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800553 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400554 main.cleanup()
555 main.exit()
556
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800558 """
andrewonlab86dc3082014-10-13 18:18:38 -0400559 Removes a cluster by ID
560 Issues command: 'remove-node [<node-id>]'
561 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800563 """
andrewonlab86dc3082014-10-13 18:18:38 -0400564 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400565
kelvin-onlabd3b64892015-01-20 13:26:24 -0800566 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700567 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800568 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700569 if re.search( "Error", handle ):
570 main.log.error( "Error in removing node" )
571 main.log.error( handle )
572 return main.FALSE
573 else:
574 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800575 except AssertionError:
576 main.log.exception( "" )
577 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800578 except TypeError:
579 main.log.exception( self.name + ": Object not as expected" )
580 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800582 main.log.error( self.name + ": EOF exception found" )
583 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400584 main.cleanup()
585 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800586 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800587 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400588 main.cleanup()
589 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590
Jon Hall61282e32015-03-19 11:34:11 -0700591 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800592 """
andrewonlab7c211572014-10-15 16:45:20 -0400593 List the nodes currently visible
594 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700595 Optional argument:
596 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800597 """
andrewonlab7c211572014-10-15 16:45:20 -0400598 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700599 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700600 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700601 cmdStr += " -j"
602 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800603 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700604 return output
Jon Hallc6793552016-01-19 14:18:37 -0800605 except AssertionError:
606 main.log.exception( "" )
607 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800608 except TypeError:
609 main.log.exception( self.name + ": Object not as expected" )
610 return None
andrewonlab7c211572014-10-15 16:45:20 -0400611 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800612 main.log.error( self.name + ": EOF exception found" )
613 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800617 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400618 main.cleanup()
619 main.exit()
620
kelvin8ec71442015-01-15 16:57:00 -0800621 def topology( self ):
622 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700623 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700624 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700625 Return:
626 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800627 """
andrewonlab95ce8322014-10-13 14:12:04 -0400628 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700629 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800631 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700632 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400633 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800634 except AssertionError:
635 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800636 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800637 except TypeError:
638 main.log.exception( self.name + ": Object not as expected" )
639 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400640 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800641 main.log.error( self.name + ": EOF exception found" )
642 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400643 main.cleanup()
644 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800645 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800646 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400647 main.cleanup()
648 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800649
jenkins7ead5a82015-03-13 10:28:21 -0700650 def deviceRemove( self, deviceId ):
651 """
652 Removes particular device from storage
653
654 TODO: refactor this function
655 """
656 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700657 cmdStr = "device-remove " + str( deviceId )
658 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800659 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 if re.search( "Error", handle ):
661 main.log.error( "Error in removing device" )
662 main.log.error( handle )
663 return main.FALSE
664 else:
665 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
jenkins7ead5a82015-03-13 10:28:21 -0700669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
672 except pexpect.EOF:
673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
675 main.cleanup()
676 main.exit()
677 except Exception:
678 main.log.exception( self.name + ": Uncaught exception!" )
679 main.cleanup()
680 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700681
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800683 """
Jon Hall7b02d952014-10-17 20:14:54 -0400684 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400685 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800687 """
andrewonlab86dc3082014-10-13 18:18:38 -0400688 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700689 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr += " -j"
692 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800693 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700694 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800695 except AssertionError:
696 main.log.exception( "" )
697 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800698 except TypeError:
699 main.log.exception( self.name + ": Object not as expected" )
700 return None
andrewonlab7c211572014-10-15 16:45:20 -0400701 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800702 main.log.error( self.name + ": EOF exception found" )
703 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400704 main.cleanup()
705 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800706 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800707 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400708 main.cleanup()
709 main.exit()
710
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800712 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800713 This balances the devices across all controllers
714 by issuing command: 'onos> onos:balance-masters'
715 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800716 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800717 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800720 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700721 if re.search( "Error", handle ):
722 main.log.error( "Error in balancing masters" )
723 main.log.error( handle )
724 return main.FALSE
725 else:
726 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800727 except AssertionError:
728 main.log.exception( "" )
729 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800730 except TypeError:
731 main.log.exception( self.name + ": Object not as expected" )
732 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800733 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800734 main.log.error( self.name + ": EOF exception found" )
735 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800736 main.cleanup()
737 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800738 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800739 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800740 main.cleanup()
741 main.exit()
742
Jon Hallc6793552016-01-19 14:18:37 -0800743 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700744 """
745 Returns the output of the masters command.
746 Optional argument:
747 * jsonFormat - boolean indicating if you want output in json
748 """
749 try:
750 cmdStr = "onos:masters"
751 if jsonFormat:
752 cmdStr += " -j"
753 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800754 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700755 return output
Jon Hallc6793552016-01-19 14:18:37 -0800756 except AssertionError:
757 main.log.exception( "" )
758 return None
acsmars24950022015-07-30 18:00:43 -0700759 except TypeError:
760 main.log.exception( self.name + ": Object not as expected" )
761 return None
762 except pexpect.EOF:
763 main.log.error( self.name + ": EOF exception found" )
764 main.log.error( self.name + ": " + self.handle.before )
765 main.cleanup()
766 main.exit()
767 except Exception:
768 main.log.exception( self.name + ": Uncaught exception!" )
769 main.cleanup()
770 main.exit()
771
Jon Hallc6793552016-01-19 14:18:37 -0800772 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700773 """
774 Uses the master command to check that the devices' leadership
775 is evenly divided
776
777 Dependencies: checkMasters() and summary()
778
779 Returns main.True if the devices are balanced
780 Returns main.False if the devices are unbalanced
781 Exits on Exception
782 Returns None on TypeError
783 """
784 try:
Jon Hallc6793552016-01-19 14:18:37 -0800785 summaryOutput = self.summary()
786 totalDevices = json.loads( summaryOutput )[ "devices" ]
787 except ( TypeError, ValueError ):
788 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
789 return None
790 try:
acsmars24950022015-07-30 18:00:43 -0700791 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800792 mastersOutput = self.checkMasters()
793 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700794 first = masters[ 0 ][ "size" ]
795 for master in masters:
796 totalOwnedDevices += master[ "size" ]
797 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
798 main.log.error( "Mastership not balanced" )
799 main.log.info( "\n" + self.checkMasters( False ) )
800 return main.FALSE
801 main.log.info( "Mastership balanced between " \
802 + str( len(masters) ) + " masters" )
803 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800804 except ( TypeError, ValueError ):
805 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700806 return None
807 except pexpect.EOF:
808 main.log.error( self.name + ": EOF exception found" )
809 main.log.error( self.name + ": " + self.handle.before )
810 main.cleanup()
811 main.exit()
812 except Exception:
813 main.log.exception( self.name + ": Uncaught exception!" )
814 main.cleanup()
815 main.exit()
816
kelvin-onlabd3b64892015-01-20 13:26:24 -0800817 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800818 """
Jon Halle8217482014-10-17 13:49:14 -0400819 Lists all core links
820 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800822 """
Jon Halle8217482014-10-17 13:49:14 -0400823 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700824 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700826 cmdStr += " -j"
827 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800828 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700829 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800830 except AssertionError:
831 main.log.exception( "" )
832 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800833 except TypeError:
834 main.log.exception( self.name + ": Object not as expected" )
835 return None
Jon Halle8217482014-10-17 13:49:14 -0400836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400839 main.cleanup()
840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800842 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400843 main.cleanup()
844 main.exit()
845
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Halle8217482014-10-17 13:49:14 -0400848 Lists all ports
849 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Halle8217482014-10-17 13:49:14 -0400852 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700853 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800854 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700855 cmdStr += " -j"
856 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800857 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700858 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800859 except AssertionError:
860 main.log.exception( "" )
861 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800862 except TypeError:
863 main.log.exception( self.name + ": Object not as expected" )
864 return None
Jon Halle8217482014-10-17 13:49:14 -0400865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400868 main.cleanup()
869 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800870 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800871 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400872 main.cleanup()
873 main.exit()
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
Jon Hall983a1702014-10-28 18:44:22 -0400877 Lists all devices and the controllers with roles assigned to them
878 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800880 """
andrewonlab7c211572014-10-15 16:45:20 -0400881 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 cmdStr += " -j"
885 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800886 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700887 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800888 except AssertionError:
889 main.log.exception( "" )
890 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800891 except TypeError:
892 main.log.exception( self.name + ": Object not as expected" )
893 return None
Jon Hall983a1702014-10-28 18:44:22 -0400894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800895 main.log.error( self.name + ": EOF exception found" )
896 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400897 main.cleanup()
898 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800899 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800900 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400901 main.cleanup()
902 main.exit()
903
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800905 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800906 Given the a string containing the json representation of the "roles"
907 cli command and a partial or whole device id, returns a json object
908 containing the roles output for the first device whose id contains
909 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400910
911 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800912 A dict of the role assignments for the given device or
913 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800914 """
Jon Hall983a1702014-10-28 18:44:22 -0400915 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400917 return None
918 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 rawRoles = self.roles()
920 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800921 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800923 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400925 return device
926 return None
Jon Hallc6793552016-01-19 14:18:37 -0800927 except ( TypeError, ValueError ):
928 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800929 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400933 main.cleanup()
934 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800935 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800936 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400937 main.cleanup()
938 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800939
kelvin-onlabd3b64892015-01-20 13:26:24 -0800940 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800941 """
Jon Hall94fd0472014-12-08 11:52:42 -0800942 Iterates through each device and checks if there is a master assigned
943 Returns: main.TRUE if each device has a master
944 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800945 """
Jon Hall94fd0472014-12-08 11:52:42 -0800946 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 rawRoles = self.roles()
948 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800949 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800950 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800951 # print device
952 if device[ 'master' ] == "none":
953 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800954 return main.FALSE
955 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800956 except ( TypeError, ValueError ):
957 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800958 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800959 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800960 main.log.error( self.name + ": EOF exception found" )
961 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800962 main.cleanup()
963 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800964 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800965 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800966 main.cleanup()
967 main.exit()
968
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800970 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400971 Returns string of paths, and the cost.
972 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800973 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400974 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
976 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800977 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800978 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( "Error in getting paths" )
980 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400981 else:
kelvin8ec71442015-01-15 16:57:00 -0800982 path = handle.split( ";" )[ 0 ]
983 cost = handle.split( ";" )[ 1 ]
984 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800985 except AssertionError:
986 main.log.exception( "" )
987 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800988 except TypeError:
989 main.log.exception( self.name + ": Object not as expected" )
990 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400991 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800992 main.log.error( self.name + ": EOF exception found" )
993 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400994 main.cleanup()
995 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800996 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800997 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400998 main.cleanup()
999 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001002 """
Jon Hallffb386d2014-11-21 13:43:38 -08001003 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001004 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001006 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001007 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001008 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001010 cmdStr += " -j"
1011 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001012 if handle:
1013 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001014 # TODO: Maybe make this less hardcoded
1015 # ConsistentMap Exceptions
1016 assert "org.onosproject.store.service" not in handle
1017 # Node not leader
1018 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001019 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001020 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001021 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001022 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001023 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001024 except TypeError:
1025 main.log.exception( self.name + ": Object not as expected" )
1026 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001027 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001028 main.log.error( self.name + ": EOF exception found" )
1029 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001030 main.cleanup()
1031 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001032 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001033 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001034 main.cleanup()
1035 main.exit()
1036
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001038 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001039 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001040
Jon Hallefbd9792015-03-05 16:11:36 -08001041 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001042 partial mac address
1043
Jon Hall42db6dc2014-10-24 19:03:48 -04001044 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 try:
kelvin8ec71442015-01-15 16:57:00 -08001047 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 return None
1049 else:
1050 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 rawHosts = self.hosts()
1052 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001053 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001055 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001056 if not host:
1057 pass
1058 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001059 return host
1060 return None
Jon Hallc6793552016-01-19 14:18:37 -08001061 except ( TypeError, ValueError ):
1062 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001063 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001065 main.log.error( self.name + ": EOF exception found" )
1066 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001067 main.cleanup()
1068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001070 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 main.cleanup()
1072 main.exit()
1073
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001075 """
1076 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001077 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001078
andrewonlab3f0a4af2014-10-17 12:25:14 -04001079 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001081 IMPORTANT:
1082 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001083 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001084 Furthermore, it assumes that value of VLAN is '-1'
1085 Description:
kelvin8ec71442015-01-15 16:57:00 -08001086 Converts mininet hosts ( h1, h2, h3... ) into
1087 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1088 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001089 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001091
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001093 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 hostHex = hex( int( host ) ).zfill( 12 )
1095 hostHex = str( hostHex ).replace( 'x', '0' )
1096 i = iter( str( hostHex ) )
1097 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1098 hostHex = hostHex + "/-1"
1099 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001100
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001102
Jon Halld4d4b372015-01-28 16:02:41 -08001103 except TypeError:
1104 main.log.exception( self.name + ": Object not as expected" )
1105 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001109 main.cleanup()
1110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001112 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001113 main.cleanup()
1114 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001117 """
andrewonlabe6745342014-10-17 14:29:13 -04001118 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 * hostIdOne: ONOS host id for host1
1120 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001121 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001122 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001123 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001124 Returns:
1125 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001126 """
andrewonlabe6745342014-10-17 14:29:13 -04001127 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1129 " " + str( hostIdTwo )
1130 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001131 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001132 if re.search( "Error", handle ):
1133 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001134 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001135 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001136 else:
1137 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001138 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1139 match = re.search('id=0x([\da-f]+),', handle)
1140 if match:
1141 return match.group()[3:-1]
1142 else:
1143 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001144 main.log.debug( "Response from ONOS was: " +
1145 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001146 return None
Jon Hallc6793552016-01-19 14:18:37 -08001147 except AssertionError:
1148 main.log.exception( "" )
1149 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001150 except TypeError:
1151 main.log.exception( self.name + ": Object not as expected" )
1152 return None
andrewonlabe6745342014-10-17 14:29:13 -04001153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001154 main.log.error( self.name + ": EOF exception found" )
1155 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001156 main.cleanup()
1157 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001159 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001160 main.cleanup()
1161 main.exit()
1162
kelvin-onlabd3b64892015-01-20 13:26:24 -08001163 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001164 """
andrewonlab7b31d232014-10-24 13:31:47 -04001165 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 * ingressDevice: device id of ingress device
1167 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001168 Optional:
1169 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 Description:
1171 Adds an optical intent by specifying an ingress and egress device
1172 Returns:
1173 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001174 """
andrewonlab7b31d232014-10-24 13:31:47 -04001175 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1177 " " + str( egressDevice )
1178 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001179 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001180 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001181 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001182 main.log.error( "Error in adding Optical intent" )
1183 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001184 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 main.log.info( "Optical intent installed between " +
1186 str( ingressDevice ) + " and " +
1187 str( egressDevice ) )
1188 match = re.search('id=0x([\da-f]+),', handle)
1189 if match:
1190 return match.group()[3:-1]
1191 else:
1192 main.log.error( "Error, intent ID not found" )
1193 return None
Jon Hallc6793552016-01-19 14:18:37 -08001194 except AssertionError:
1195 main.log.exception( "" )
1196 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001197 except TypeError:
1198 main.log.exception( self.name + ": Object not as expected" )
1199 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001200 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001201 main.log.error( self.name + ": EOF exception found" )
1202 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001203 main.cleanup()
1204 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001205 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001206 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001207 main.cleanup()
1208 main.exit()
1209
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001211 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 ingressDevice,
1213 egressDevice,
1214 portIngress="",
1215 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 ethType="",
1217 ethSrc="",
1218 ethDst="",
1219 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001221 ipProto="",
1222 ipSrc="",
1223 ipDst="",
1224 tcpSrc="",
1225 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001226 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001227 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 * ingressDevice: device id of ingress device
1229 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001230 Optional:
1231 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001232 * ethSrc: specify ethSrc ( i.e. src mac addr )
1233 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001234 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001236 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001237 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001238 * ipSrc: specify ip source address
1239 * ipDst: specify ip destination address
1240 * tcpSrc: specify tcp source port
1241 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001242 Description:
kelvin8ec71442015-01-15 16:57:00 -08001243 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001244 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001245 Returns:
1246 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001247
Jon Halle3f39ff2015-01-13 11:50:53 -08001248 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001249 options developers provide for point-to-point
1250 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001251 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001252 try:
kelvin8ec71442015-01-15 16:57:00 -08001253 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001254 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001256 and not ipProto and not ipSrc and not ipDst \
1257 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001258 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001259
andrewonlab289e4b72014-10-21 21:24:18 -04001260 else:
andrewonlab36af3822014-11-18 17:48:18 -05001261 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001262
andrewonlab0c0a6772014-10-22 12:31:18 -04001263 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001264 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001265 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " --ethSrc " + str( ethSrc )
1267 if ethDst:
1268 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001269 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001270 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001272 cmd += " --lambda "
1273 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001274 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001275 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001276 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001277 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001278 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001279 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001280 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001281 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001282 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001283
kelvin8ec71442015-01-15 16:57:00 -08001284 # Check whether the user appended the port
1285 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 if "/" in ingressDevice:
1287 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001288 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001290 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001291 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001292 # Would it make sense to throw an exception and exit
1293 # the test?
1294 return None
andrewonlab36af3822014-11-18 17:48:18 -05001295
kelvin8ec71442015-01-15 16:57:00 -08001296 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 str( ingressDevice ) + "/" +\
1298 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001299
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 if "/" in egressDevice:
1301 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001302 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001304 main.log.error( "You must specify the egress port" )
1305 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001306
kelvin8ec71442015-01-15 16:57:00 -08001307 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 str( egressDevice ) + "/" +\
1309 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001310
kelvin-onlab898a6c62015-01-16 14:13:53 -08001311 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001312 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001313 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001314 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001315 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001316 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001317 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001318 # TODO: print out all the options in this message?
1319 main.log.info( "Point-to-point intent installed between " +
1320 str( ingressDevice ) + " and " +
1321 str( egressDevice ) )
1322 match = re.search('id=0x([\da-f]+),', handle)
1323 if match:
1324 return match.group()[3:-1]
1325 else:
1326 main.log.error( "Error, intent ID not found" )
1327 return None
Jon Hallc6793552016-01-19 14:18:37 -08001328 except AssertionError:
1329 main.log.exception( "" )
1330 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001331 except TypeError:
1332 main.log.exception( self.name + ": Object not as expected" )
1333 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001334 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001335 main.log.error( self.name + ": EOF exception found" )
1336 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001337 main.cleanup()
1338 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001339 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001340 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001341 main.cleanup()
1342 main.exit()
1343
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001345 self,
shahshreyac2f97072015-03-19 17:04:29 -07001346 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001348 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001350 ethType="",
1351 ethSrc="",
1352 ethDst="",
1353 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001355 ipProto="",
1356 ipSrc="",
1357 ipDst="",
1358 tcpSrc="",
1359 tcpDst="",
1360 setEthSrc="",
1361 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001362 """
shahshreyad0c80432014-12-04 16:56:05 -08001363 Note:
shahshreya70622b12015-03-19 17:19:00 -07001364 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001365 is same. That is, all ingress devices include port numbers
1366 with a "/" or all ingress devices could specify device
1367 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001368 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001369 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001370 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001372 Optional:
1373 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001374 * ethSrc: specify ethSrc ( i.e. src mac addr )
1375 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001376 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001378 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001379 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001380 * ipSrc: specify ip source address
1381 * ipDst: specify ip destination address
1382 * tcpSrc: specify tcp source port
1383 * tcpDst: specify tcp destination port
1384 * setEthSrc: action to Rewrite Source MAC Address
1385 * setEthDst: action to Rewrite Destination MAC Address
1386 Description:
kelvin8ec71442015-01-15 16:57:00 -08001387 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001388 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001389 Returns:
1390 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001391
Jon Halle3f39ff2015-01-13 11:50:53 -08001392 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001393 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001394 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001395 """
shahshreyad0c80432014-12-04 16:56:05 -08001396 try:
kelvin8ec71442015-01-15 16:57:00 -08001397 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001398 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001400 and not ipProto and not ipSrc and not ipDst\
1401 and not tcpSrc and not tcpDst and not setEthSrc\
1402 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001403 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001404
1405 else:
1406 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001407
shahshreyad0c80432014-12-04 16:56:05 -08001408 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001409 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001410 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001411 cmd += " --ethSrc " + str( ethSrc )
1412 if ethDst:
1413 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001414 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001415 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001417 cmd += " --lambda "
1418 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001419 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001420 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001421 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001422 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001423 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001424 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001425 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001426 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001427 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001428 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001429 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001430 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001431 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001432
kelvin8ec71442015-01-15 16:57:00 -08001433 # Check whether the user appended the port
1434 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001435
1436 if portIngressList is None:
1437 for ingressDevice in ingressDeviceList:
1438 if "/" in ingressDevice:
1439 cmd += " " + str( ingressDevice )
1440 else:
1441 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001442 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001443 # TODO: perhaps more meaningful return
1444 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001445 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001446 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001447 for ingressDevice, portIngress in zip( ingressDeviceList,
1448 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001449 cmd += " " + \
1450 str( ingressDevice ) + "/" +\
1451 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001452 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001453 main.log.error( "Device list and port list does not " +
1454 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001455 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001456 if "/" in egressDevice:
1457 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001458 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001459 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001460 main.log.error( "You must specify " +
1461 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001462 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001463
kelvin8ec71442015-01-15 16:57:00 -08001464 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 str( egressDevice ) + "/" +\
1466 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001467 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001468 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001469 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001470 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001471 main.log.error( "Error in adding multipoint-to-singlepoint " +
1472 "intent" )
1473 return None
shahshreyad0c80432014-12-04 16:56:05 -08001474 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001475 match = re.search('id=0x([\da-f]+),', handle)
1476 if match:
1477 return match.group()[3:-1]
1478 else:
1479 main.log.error( "Error, intent ID not found" )
1480 return None
Jon Hallc6793552016-01-19 14:18:37 -08001481 except AssertionError:
1482 main.log.exception( "" )
1483 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001484 except TypeError:
1485 main.log.exception( self.name + ": Object not as expected" )
1486 return None
1487 except pexpect.EOF:
1488 main.log.error( self.name + ": EOF exception found" )
1489 main.log.error( self.name + ": " + self.handle.before )
1490 main.cleanup()
1491 main.exit()
1492 except Exception:
1493 main.log.exception( self.name + ": Uncaught exception!" )
1494 main.cleanup()
1495 main.exit()
1496
1497 def addSinglepointToMultipointIntent(
1498 self,
1499 ingressDevice,
1500 egressDeviceList,
1501 portIngress="",
1502 portEgressList=None,
1503 ethType="",
1504 ethSrc="",
1505 ethDst="",
1506 bandwidth="",
1507 lambdaAlloc=False,
1508 ipProto="",
1509 ipSrc="",
1510 ipDst="",
1511 tcpSrc="",
1512 tcpDst="",
1513 setEthSrc="",
1514 setEthDst="" ):
1515 """
1516 Note:
1517 This function assumes the format of all egress devices
1518 is same. That is, all egress devices include port numbers
1519 with a "/" or all egress devices could specify device
1520 ids and port numbers seperately.
1521 Required:
1522 * EgressDeviceList: List of device ids of egress device
1523 ( Atleast 2 eress devices required in the list )
1524 * ingressDevice: device id of ingress device
1525 Optional:
1526 * ethType: specify ethType
1527 * ethSrc: specify ethSrc ( i.e. src mac addr )
1528 * ethDst: specify ethDst ( i.e. dst mac addr )
1529 * bandwidth: specify bandwidth capacity of link
1530 * lambdaAlloc: if True, intent will allocate lambda
1531 for the specified intent
1532 * ipProto: specify ip protocol
1533 * ipSrc: specify ip source address
1534 * ipDst: specify ip destination address
1535 * tcpSrc: specify tcp source port
1536 * tcpDst: specify tcp destination port
1537 * setEthSrc: action to Rewrite Source MAC Address
1538 * setEthDst: action to Rewrite Destination MAC Address
1539 Description:
1540 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1541 specifying device id's and optional fields
1542 Returns:
1543 A string of the intent id or None on error
1544
1545 NOTE: This function may change depending on the
1546 options developers provide for singlepoint-to-multipoint
1547 intent via cli
1548 """
1549 try:
1550 # If there are no optional arguments
1551 if not ethType and not ethSrc and not ethDst\
1552 and not bandwidth and not lambdaAlloc\
1553 and not ipProto and not ipSrc and not ipDst\
1554 and not tcpSrc and not tcpDst and not setEthSrc\
1555 and not setEthDst:
1556 cmd = "add-single-to-multi-intent"
1557
1558 else:
1559 cmd = "add-single-to-multi-intent"
1560
1561 if ethType:
1562 cmd += " --ethType " + str( ethType )
1563 if ethSrc:
1564 cmd += " --ethSrc " + str( ethSrc )
1565 if ethDst:
1566 cmd += " --ethDst " + str( ethDst )
1567 if bandwidth:
1568 cmd += " --bandwidth " + str( bandwidth )
1569 if lambdaAlloc:
1570 cmd += " --lambda "
1571 if ipProto:
1572 cmd += " --ipProto " + str( ipProto )
1573 if ipSrc:
1574 cmd += " --ipSrc " + str( ipSrc )
1575 if ipDst:
1576 cmd += " --ipDst " + str( ipDst )
1577 if tcpSrc:
1578 cmd += " --tcpSrc " + str( tcpSrc )
1579 if tcpDst:
1580 cmd += " --tcpDst " + str( tcpDst )
1581 if setEthSrc:
1582 cmd += " --setEthSrc " + str( setEthSrc )
1583 if setEthDst:
1584 cmd += " --setEthDst " + str( setEthDst )
1585
1586 # Check whether the user appended the port
1587 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001588
kelvin-onlabb9408212015-04-01 13:34:04 -07001589 if "/" in ingressDevice:
1590 cmd += " " + str( ingressDevice )
1591 else:
1592 if not portIngress:
1593 main.log.error( "You must specify " +
1594 "the Ingress port" )
1595 return main.FALSE
1596
1597 cmd += " " +\
1598 str( ingressDevice ) + "/" +\
1599 str( portIngress )
1600
1601 if portEgressList is None:
1602 for egressDevice in egressDeviceList:
1603 if "/" in egressDevice:
1604 cmd += " " + str( egressDevice )
1605 else:
1606 main.log.error( "You must specify " +
1607 "the egress port" )
1608 # TODO: perhaps more meaningful return
1609 return main.FALSE
1610 else:
1611 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001612 for egressDevice, portEgress in zip( egressDeviceList,
1613 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001614 cmd += " " + \
1615 str( egressDevice ) + "/" +\
1616 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001617 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001618 main.log.error( "Device list and port list does not " +
1619 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001620 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001621 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001622 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001623 # If error, return error message
1624 if re.search( "Error", handle ):
1625 main.log.error( "Error in adding singlepoint-to-multipoint " +
1626 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001627 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001628 else:
1629 match = re.search('id=0x([\da-f]+),', handle)
1630 if match:
1631 return match.group()[3:-1]
1632 else:
1633 main.log.error( "Error, intent ID not found" )
1634 return None
Jon Hallc6793552016-01-19 14:18:37 -08001635 except AssertionError:
1636 main.log.exception( "" )
1637 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001638 except TypeError:
1639 main.log.exception( self.name + ": Object not as expected" )
1640 return None
shahshreyad0c80432014-12-04 16:56:05 -08001641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001642 main.log.error( self.name + ": EOF exception found" )
1643 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001644 main.cleanup()
1645 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001646 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001647 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001648 main.cleanup()
1649 main.exit()
1650
Hari Krishna9e232602015-04-13 17:29:08 -07001651 def addMplsIntent(
1652 self,
1653 ingressDevice,
1654 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001655 ingressPort="",
1656 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001657 ethType="",
1658 ethSrc="",
1659 ethDst="",
1660 bandwidth="",
1661 lambdaAlloc=False,
1662 ipProto="",
1663 ipSrc="",
1664 ipDst="",
1665 tcpSrc="",
1666 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001667 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001668 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001669 priority=""):
1670 """
1671 Required:
1672 * ingressDevice: device id of ingress device
1673 * egressDevice: device id of egress device
1674 Optional:
1675 * ethType: specify ethType
1676 * ethSrc: specify ethSrc ( i.e. src mac addr )
1677 * ethDst: specify ethDst ( i.e. dst mac addr )
1678 * bandwidth: specify bandwidth capacity of link
1679 * lambdaAlloc: if True, intent will allocate lambda
1680 for the specified intent
1681 * ipProto: specify ip protocol
1682 * ipSrc: specify ip source address
1683 * ipDst: specify ip destination address
1684 * tcpSrc: specify tcp source port
1685 * tcpDst: specify tcp destination port
1686 * ingressLabel: Ingress MPLS label
1687 * egressLabel: Egress MPLS label
1688 Description:
1689 Adds MPLS intent by
1690 specifying device id's and optional fields
1691 Returns:
1692 A string of the intent id or None on error
1693
1694 NOTE: This function may change depending on the
1695 options developers provide for MPLS
1696 intent via cli
1697 """
1698 try:
1699 # If there are no optional arguments
1700 if not ethType and not ethSrc and not ethDst\
1701 and not bandwidth and not lambdaAlloc \
1702 and not ipProto and not ipSrc and not ipDst \
1703 and not tcpSrc and not tcpDst and not ingressLabel \
1704 and not egressLabel:
1705 cmd = "add-mpls-intent"
1706
1707 else:
1708 cmd = "add-mpls-intent"
1709
1710 if ethType:
1711 cmd += " --ethType " + str( ethType )
1712 if ethSrc:
1713 cmd += " --ethSrc " + str( ethSrc )
1714 if ethDst:
1715 cmd += " --ethDst " + str( ethDst )
1716 if bandwidth:
1717 cmd += " --bandwidth " + str( bandwidth )
1718 if lambdaAlloc:
1719 cmd += " --lambda "
1720 if ipProto:
1721 cmd += " --ipProto " + str( ipProto )
1722 if ipSrc:
1723 cmd += " --ipSrc " + str( ipSrc )
1724 if ipDst:
1725 cmd += " --ipDst " + str( ipDst )
1726 if tcpSrc:
1727 cmd += " --tcpSrc " + str( tcpSrc )
1728 if tcpDst:
1729 cmd += " --tcpDst " + str( tcpDst )
1730 if ingressLabel:
1731 cmd += " --ingressLabel " + str( ingressLabel )
1732 if egressLabel:
1733 cmd += " --egressLabel " + str( egressLabel )
1734 if priority:
1735 cmd += " --priority " + str( priority )
1736
1737 # Check whether the user appended the port
1738 # or provided it as an input
1739 if "/" in ingressDevice:
1740 cmd += " " + str( ingressDevice )
1741 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001742 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001743 main.log.error( "You must specify the ingress port" )
1744 return None
1745
1746 cmd += " " + \
1747 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001748 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001749
1750 if "/" in egressDevice:
1751 cmd += " " + str( egressDevice )
1752 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001753 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001754 main.log.error( "You must specify the egress port" )
1755 return None
1756
1757 cmd += " " +\
1758 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001759 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001760
1761 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001762 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001763 # If error, return error message
1764 if re.search( "Error", handle ):
1765 main.log.error( "Error in adding mpls intent" )
1766 return None
1767 else:
1768 # TODO: print out all the options in this message?
1769 main.log.info( "MPLS intent installed between " +
1770 str( ingressDevice ) + " and " +
1771 str( egressDevice ) )
1772 match = re.search('id=0x([\da-f]+),', handle)
1773 if match:
1774 return match.group()[3:-1]
1775 else:
1776 main.log.error( "Error, intent ID not found" )
1777 return None
Jon Hallc6793552016-01-19 14:18:37 -08001778 except AssertionError:
1779 main.log.exception( "" )
1780 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001781 except TypeError:
1782 main.log.exception( self.name + ": Object not as expected" )
1783 return None
1784 except pexpect.EOF:
1785 main.log.error( self.name + ": EOF exception found" )
1786 main.log.error( self.name + ": " + self.handle.before )
1787 main.cleanup()
1788 main.exit()
1789 except Exception:
1790 main.log.exception( self.name + ": Uncaught exception!" )
1791 main.cleanup()
1792 main.exit()
1793
Jon Hallefbd9792015-03-05 16:11:36 -08001794 def removeIntent( self, intentId, app='org.onosproject.cli',
1795 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001796 """
shahshreya1c818fc2015-02-26 13:44:08 -08001797 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001798 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001799 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001800 -p or --purge: Purge the intent from the store after removal
1801
Jon Halle3f39ff2015-01-13 11:50:53 -08001802 Returns:
1803 main.False on error and
1804 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001805 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001806 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001807 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001808 if purge:
1809 cmdStr += " -p"
1810 if sync:
1811 cmdStr += " -s"
1812
1813 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001814 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001815 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001816 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001817 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001818 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001819 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001820 # TODO: Should this be main.TRUE
1821 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001822 except AssertionError:
1823 main.log.exception( "" )
1824 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001828 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001831 main.cleanup()
1832 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001833 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001834 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001835 main.cleanup()
1836 main.exit()
1837
Jeremy42df2e72016-02-23 16:37:46 -08001838 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1839 """
1840 Description:
1841 Remove all the intents
1842 Optional args:-
1843 -s or --sync: Waits for the removal before returning
1844 -p or --purge: Purge the intent from the store after removal
1845 Returns:
1846 Returns main.TRUE if all intents are removed, otherwise returns
1847 main.FALSE; Returns None for exception
1848 """
1849 try:
1850 cmdStr = "remove-intent"
1851 if purge:
1852 cmdStr += " -p"
1853 if sync:
1854 cmdStr += " -s"
1855
1856 cmdStr += " " + app
1857 handle = self.sendline( cmdStr )
1858 assert "Command not found:" not in handle, handle
1859 if re.search( "Error", handle ):
1860 main.log.error( "Error in removing intent" )
1861 return main.FALSE
1862 else:
1863 return main.TRUE
1864 except AssertionError:
1865 main.log.exception( "" )
1866 return None
1867 except TypeError:
1868 main.log.exception( self.name + ": Object not as expected" )
1869 return None
1870 except pexpect.EOF:
1871 main.log.error( self.name + ": EOF exception found" )
1872 main.log.error( self.name + ": " + self.handle.before )
1873 main.cleanup()
1874 main.exit()
1875 except Exception:
1876 main.log.exception( self.name + ": Uncaught exception!" )
1877 main.cleanup()
1878 main.exit()
1879
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001880 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001881 """
1882 Purges all WITHDRAWN Intents
1883 """
1884 try:
1885 cmdStr = "purge-intents"
1886 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001887 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001888 if re.search( "Error", handle ):
1889 main.log.error( "Error in purging intents" )
1890 return main.FALSE
1891 else:
1892 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001893 except AssertionError:
1894 main.log.exception( "" )
1895 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001896 except TypeError:
1897 main.log.exception( self.name + ": Object not as expected" )
1898 return None
1899 except pexpect.EOF:
1900 main.log.error( self.name + ": EOF exception found" )
1901 main.log.error( self.name + ": " + self.handle.before )
1902 main.cleanup()
1903 main.exit()
1904 except Exception:
1905 main.log.exception( self.name + ": Uncaught exception!" )
1906 main.cleanup()
1907 main.exit()
1908
kelvin-onlabd3b64892015-01-20 13:26:24 -08001909 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001910 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001911 NOTE: This method should be used after installing application:
1912 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001913 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001914 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001915 Description:
1916 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001917 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001918 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001919 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001921 cmdStr += " -j"
1922 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001923 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001924 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001925 except AssertionError:
1926 main.log.exception( "" )
1927 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001928 except TypeError:
1929 main.log.exception( self.name + ": Object not as expected" )
1930 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001931 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001932 main.log.error( self.name + ": EOF exception found" )
1933 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001934 main.cleanup()
1935 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001936 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001937 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001938 main.cleanup()
1939 main.exit()
1940
pingping-lin54b03372015-08-13 14:43:10 -07001941 def ipv4RouteNumber( self ):
1942 """
1943 NOTE: This method should be used after installing application:
1944 onos-app-sdnip
1945 Description:
1946 Obtain the total IPv4 routes number in the system
1947 """
1948 try:
1949 cmdStr = "routes -s -j"
1950 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001951 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001952 jsonResult = json.loads( handle )
1953 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001954 except AssertionError:
1955 main.log.exception( "" )
1956 return None
1957 except ( TypeError, ValueError ):
1958 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001959 return None
1960 except pexpect.EOF:
1961 main.log.error( self.name + ": EOF exception found" )
1962 main.log.error( self.name + ": " + self.handle.before )
1963 main.cleanup()
1964 main.exit()
1965 except Exception:
1966 main.log.exception( self.name + ": Uncaught exception!" )
1967 main.cleanup()
1968 main.exit()
1969
pingping-lin8244a3b2015-09-16 13:36:56 -07001970 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001971 """
andrewonlabe6745342014-10-17 14:29:13 -04001972 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001973 Obtain intents from the ONOS cli.
1974 Optional:
1975 * jsonFormat: Enable output formatting in json, default to True
1976 * summary: Whether only output the intent summary, defaults to False
1977 * type: Only output a certain type of intent. This options is valid
1978 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001979 """
andrewonlabe6745342014-10-17 14:29:13 -04001980 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001981 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001982 if summary:
1983 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001985 cmdStr += " -j"
1986 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001987 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001988 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001989 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001990 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001991 else:
Jon Hallff566d52016-01-15 14:45:36 -08001992 intentType = ""
1993 # IF we want the summary of a specific intent type
1994 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001995 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001996 if intentType in jsonResult.keys():
1997 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001998 else:
Jon Hallff566d52016-01-15 14:45:36 -08001999 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002000 return handle
2001 else:
2002 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002003 except AssertionError:
2004 main.log.exception( "" )
2005 return None
2006 except ( TypeError, ValueError ):
2007 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002008 return None
2009 except pexpect.EOF:
2010 main.log.error( self.name + ": EOF exception found" )
2011 main.log.error( self.name + ": " + self.handle.before )
2012 main.cleanup()
2013 main.exit()
2014 except Exception:
2015 main.log.exception( self.name + ": Uncaught exception!" )
2016 main.cleanup()
2017 main.exit()
2018
kelvin-onlab54400a92015-02-26 18:05:51 -08002019 def getIntentState(self, intentsId, intentsJson=None):
2020 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002021 Check intent state.
2022 Accepts a single intent ID (string type) or a list of intent IDs.
2023 Returns the state(string type) of the id if a single intent ID is
2024 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08002025 Returns a dictionary with intent IDs as the key and its
2026 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08002027 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08002028 intentId: intent ID (string type)
2029 intentsJson: parsed json object from the onos:intents api
2030 Returns:
2031 state = An intent's state- INSTALL,WITHDRAWN etc.
2032 stateDict = Dictionary of intent's state. intent ID as the keys and
2033 state as the values.
2034 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002035 try:
2036 state = "State is Undefined"
2037 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002038 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002039 else:
Jon Hallc6793552016-01-19 14:18:37 -08002040 rawJson = intentsJson
2041 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002042 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002043 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002044 if intentsId == intent[ 'id' ]:
2045 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002046 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002047 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2048 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002049 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002050 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002051 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002052 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002053 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002054 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002055 if intentsId[ i ] == intents[ 'id' ]:
2056 stateDict[ 'state' ] = intents[ 'state' ]
2057 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002058 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002059 break
Jon Hallefbd9792015-03-05 16:11:36 -08002060 if len( intentsId ) != len( dictList ):
2061 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002062 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002064 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002065 return None
Jon Hallc6793552016-01-19 14:18:37 -08002066 except ( TypeError, ValueError ):
2067 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002068 return None
2069 except pexpect.EOF:
2070 main.log.error( self.name + ": EOF exception found" )
2071 main.log.error( self.name + ": " + self.handle.before )
2072 main.cleanup()
2073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002074 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002076 main.cleanup()
2077 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002078
kelvin-onlabf512e942015-06-08 19:42:59 -07002079 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002080 """
2081 Description:
2082 Check intents state
2083 Required:
2084 intentsId - List of intents ID to be checked
2085 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002086 expectedState - Check the expected state(s) of each intents
2087 state in the list.
2088 *NOTE: You can pass in a list of expected state,
2089 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002090 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002091 Returns main.TRUE only if all intent are the same as expected states
2092 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002093 """
2094 try:
2095 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002096 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002097 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002099 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002100 "getting intents state" )
2101 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002102
2103 if isinstance( expectedState, types.StringType ):
2104 for intents in intentsDict:
2105 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002106 main.log.debug( self.name + " : Intent ID - " +
2107 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002108 " actual state = " +
2109 intents.get( 'state' )
2110 + " does not equal expected state = "
2111 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002112 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002113
2114 elif isinstance( expectedState, types.ListType ):
2115 for intents in intentsDict:
2116 if not any( state == intents.get( 'state' ) for state in
2117 expectedState ):
2118 main.log.debug( self.name + " : Intent ID - " +
2119 intents.get( 'id' ) +
2120 " actual state = " +
2121 intents.get( 'state' ) +
2122 " does not equal expected states = "
2123 + str( expectedState ) )
2124 returnValue = main.FALSE
2125
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002126 if returnValue == main.TRUE:
2127 main.log.info( self.name + ": All " +
2128 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 " intents are in " + str( expectedState ) +
2130 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 return returnValue
2132 except TypeError:
2133 main.log.exception( self.name + ": Object not as expected" )
2134 return None
2135 except pexpect.EOF:
2136 main.log.error( self.name + ": EOF exception found" )
2137 main.log.error( self.name + ": " + self.handle.before )
2138 main.cleanup()
2139 main.exit()
2140 except Exception:
2141 main.log.exception( self.name + ": Uncaught exception!" )
2142 main.cleanup()
2143 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002144
GlennRCed771242016-01-13 17:02:47 -08002145 def checkIntentSummary( self, timeout=60 ):
2146 """
2147 Description:
2148 Check the number of installed intents.
2149 Optional:
2150 timeout - the timeout for pexcept
2151 Return:
2152 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2153 , otherwise, returns main.FALSE.
2154 """
2155
2156 try:
2157 cmd = "intents -s -j"
2158
2159 # Check response if something wrong
2160 response = self.sendline( cmd, timeout=timeout )
2161 if response == None:
2162 return main.False
2163 response = json.loads( response )
2164
2165 # get total and installed number, see if they are match
2166 allState = response.get( 'all' )
2167 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002168 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002169 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002170 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002171 return main.FALSE
2172
Jon Hallc6793552016-01-19 14:18:37 -08002173 except ( TypeError, ValueError ):
2174 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002175 return None
2176 except pexpect.EOF:
2177 main.log.error( self.name + ": EOF exception found" )
2178 main.log.error( self.name + ": " + self.handle.before )
2179 main.cleanup()
2180 main.exit()
2181 except Exception:
2182 main.log.exception( self.name + ": Uncaught exception!" )
2183 main.cleanup()
2184 main.exit()
2185
2186 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002187 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002188 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002189 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002190 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002191 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002192 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002193 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002194 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002196 cmdStr += " -j "
2197 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002198 handle = self.sendline( cmdStr, timeout=timeout )
2199 assert "Command not found:" not in handle, handle
2200 if re.search( "Error:", handle ):
2201 main.log.error( self.name + ": flows() response: " +
2202 str( handle ) )
2203 return handle
2204 except AssertionError:
2205 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002206 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002207 except TypeError:
2208 main.log.exception( self.name + ": Object not as expected" )
2209 return None
Jon Hallc6793552016-01-19 14:18:37 -08002210 except pexpect.TIMEOUT:
2211 main.log.error( self.name + ": ONOS timeout" )
2212 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002214 main.log.error( self.name + ": EOF exception found" )
2215 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002216 main.cleanup()
2217 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002218 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002219 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002220 main.cleanup()
2221 main.exit()
2222
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002223 def checkFlowCount(self, min=0, timeout=60 ):
2224 count = int(self.getTotalFlowsNum( timeout=timeout ))
2225 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002226
Jon Hallc6793552016-01-19 14:18:37 -08002227 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002228 """
2229 Description:
GlennRCed771242016-01-13 17:02:47 -08002230 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002231 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2232 if the count of those states is 0, which means all current flows
2233 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002234 Optional:
GlennRCed771242016-01-13 17:02:47 -08002235 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002236 Return:
2237 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002238 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002239 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002240 """
2241 try:
GlennRCed771242016-01-13 17:02:47 -08002242 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2243 checkedStates = []
2244 statesCount = [0, 0, 0, 0]
2245 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002246 rawFlows = self.flows( state=s, timeout = timeout )
2247 checkedStates.append( json.loads( rawFlows ) )
2248 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002249 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002250 try:
2251 statesCount[i] += int( c.get( "flowCount" ) )
2252 except TypeError:
2253 main.log.exception( "Json object not as expected" )
2254 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002255
GlennRCed771242016-01-13 17:02:47 -08002256 # We want to count PENDING_ADD if isPENDING is true
2257 if isPENDING:
2258 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2259 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002260 else:
GlennRCed771242016-01-13 17:02:47 -08002261 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2262 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002263 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002264 except ( TypeError, ValueError ):
2265 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002266 return None
2267 except pexpect.EOF:
2268 main.log.error( self.name + ": EOF exception found" )
2269 main.log.error( self.name + ": " + self.handle.before )
2270 main.cleanup()
2271 main.exit()
2272 except Exception:
2273 main.log.exception( self.name + ": Uncaught exception!" )
2274 main.cleanup()
2275 main.exit()
2276
GlennRCed771242016-01-13 17:02:47 -08002277 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2278 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002279 """
andrewonlab87852b02014-11-19 18:44:19 -05002280 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002281 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002282 a specific point-to-point intent definition
2283 Required:
GlennRCed771242016-01-13 17:02:47 -08002284 * ingress: specify source dpid
2285 * egress: specify destination dpid
2286 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002287 Optional:
GlennRCed771242016-01-13 17:02:47 -08002288 * offset: the keyOffset is where the next batch of intents
2289 will be installed
2290 Returns: If failed to push test intents, it will returen None,
2291 if successful, return true.
2292 Timeout expection will return None,
2293 TypeError will return false
2294 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002295 """
andrewonlab87852b02014-11-19 18:44:19 -05002296 try:
GlennRCed771242016-01-13 17:02:47 -08002297 if background:
2298 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002299 else:
GlennRCed771242016-01-13 17:02:47 -08002300 back = ""
2301 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002302 ingress,
2303 egress,
2304 batchSize,
2305 offset,
2306 back )
GlennRCed771242016-01-13 17:02:47 -08002307 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002308 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002309 main.log.info( response )
2310 if response == None:
2311 return None
2312
2313 # TODO: We should handle if there is failure in installation
2314 return main.TRUE
2315
Jon Hallc6793552016-01-19 14:18:37 -08002316 except AssertionError:
2317 main.log.exception( "" )
2318 return None
GlennRCed771242016-01-13 17:02:47 -08002319 except pexpect.TIMEOUT:
2320 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002321 return None
andrewonlab87852b02014-11-19 18:44:19 -05002322 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002325 main.cleanup()
2326 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002327 except TypeError:
2328 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002329 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002330 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002331 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002332 main.cleanup()
2333 main.exit()
2334
YPZhangf6f14a02016-01-28 15:17:31 -08002335 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002336 """
2337 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002338 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002339 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002340 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002341 """
YPZhange3109a72016-02-02 11:25:37 -08002342
YPZhangb5d3f832016-01-23 22:54:26 -08002343 try:
YPZhange3109a72016-02-02 11:25:37 -08002344 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002345 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002346 totalFlows = self.sendline( cmd, timeout=timeout )
2347
2348 if totalFlows == None:
2349 # if timeout, we will get total number of all flows, and subtract other states
2350 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2351 checkedStates = []
2352 totalFlows = 0
2353 statesCount = [0, 0, 0, 0]
2354
2355 # get total flows from summary
2356 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2357 totalFlows = int( response.get("flows") )
2358
2359 for s in states:
2360 rawFlows = self.flows( state=s, timeout = timeout )
2361 if rawFlows == None:
2362 # if timeout, return the total flows number from summary command
2363 return totalFlows
2364 checkedStates.append( json.loads( rawFlows ) )
2365
2366 # Calculate ADDED flows number, equal total subtracts others
2367 for i in range( len( states ) ):
2368 for c in checkedStates[i]:
2369 try:
2370 statesCount[i] += int( c.get( "flowCount" ) )
2371 except TypeError:
2372 main.log.exception( "Json object not as expected" )
2373 totalFlows = totalFlows - int( statesCount[i] )
2374 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2375
2376 return totalFlows
2377
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002378 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002379
YPZhangb5d3f832016-01-23 22:54:26 -08002380 except TypeError:
2381 main.log.exception( self.name + ": Object not as expected" )
2382 return None
2383 except pexpect.EOF:
2384 main.log.error( self.name + ": EOF exception found" )
2385 main.log.error( self.name + ": " + self.handle.before )
2386 main.cleanup()
2387 main.exit()
2388 except Exception:
2389 main.log.exception( self.name + ": Uncaught exception!" )
2390 main.cleanup()
2391 main.exit()
2392
2393 def getTotalIntentsNum( self ):
2394 """
2395 Description:
2396 Get the total number of intents, include every states.
2397 Return:
2398 The number of intents
2399 """
2400 try:
2401 cmd = "summary -j"
2402 response = self.sendline( cmd )
2403 if response == None:
2404 return -1
2405 response = json.loads( response )
2406 return int( response.get("intents") )
2407 except TypeError:
2408 main.log.exception( self.name + ": Object not as expected" )
2409 return None
2410 except pexpect.EOF:
2411 main.log.error( self.name + ": EOF exception found" )
2412 main.log.error( self.name + ": " + self.handle.before )
2413 main.cleanup()
2414 main.exit()
2415 except Exception:
2416 main.log.exception( self.name + ": Uncaught exception!" )
2417 main.cleanup()
2418 main.exit()
2419
kelvin-onlabd3b64892015-01-20 13:26:24 -08002420 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002421 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002422 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002423 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002424 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002425 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002426 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002427 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002428 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002429 cmdStr += " -j"
2430 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002431 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002432 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002433 except AssertionError:
2434 main.log.exception( "" )
2435 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002436 except TypeError:
2437 main.log.exception( self.name + ": Object not as expected" )
2438 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002440 main.log.error( self.name + ": EOF exception found" )
2441 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002442 main.cleanup()
2443 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002445 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002446 main.cleanup()
2447 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002448
kelvin-onlabd3b64892015-01-20 13:26:24 -08002449 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002450 """
2451 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002452 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002453 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002454 """
andrewonlab867212a2014-10-22 20:13:38 -04002455 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002456 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002458 cmdStr += " -j"
2459 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002460 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002461 if handle:
2462 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002463 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002464 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002465 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002466 else:
2467 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002468 except AssertionError:
2469 main.log.exception( "" )
2470 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002471 except TypeError:
2472 main.log.exception( self.name + ": Object not as expected" )
2473 return None
andrewonlab867212a2014-10-22 20:13:38 -04002474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002475 main.log.error( self.name + ": EOF exception found" )
2476 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002477 main.cleanup()
2478 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002479 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002480 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002481 main.cleanup()
2482 main.exit()
2483
kelvin8ec71442015-01-15 16:57:00 -08002484 # Wrapper functions ****************
2485 # Wrapper functions use existing driver
2486 # functions and extends their use case.
2487 # For example, we may use the output of
2488 # a normal driver function, and parse it
2489 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002490
kelvin-onlabd3b64892015-01-20 13:26:24 -08002491 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002492 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002493 Description:
2494 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002495 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002496 try:
kelvin8ec71442015-01-15 16:57:00 -08002497 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002498 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002499 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002500
kelvin8ec71442015-01-15 16:57:00 -08002501 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002502 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2503 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002504 match = re.search('id=0x([\da-f]+),', intents)
2505 if match:
2506 tmpId = match.group()[3:-1]
2507 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002509
Jon Halld4d4b372015-01-28 16:02:41 -08002510 except TypeError:
2511 main.log.exception( self.name + ": Object not as expected" )
2512 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002513 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002514 main.log.error( self.name + ": EOF exception found" )
2515 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002516 main.cleanup()
2517 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002518 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002519 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002520 main.cleanup()
2521 main.exit()
2522
Jon Hall30b82fa2015-03-04 17:15:43 -08002523 def FlowAddedCount( self, deviceId ):
2524 """
2525 Determine the number of flow rules for the given device id that are
2526 in the added state
2527 """
2528 try:
2529 cmdStr = "flows any " + str( deviceId ) + " | " +\
2530 "grep 'state=ADDED' | wc -l"
2531 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002532 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002533 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002534 except AssertionError:
2535 main.log.exception( "" )
2536 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002537 except pexpect.EOF:
2538 main.log.error( self.name + ": EOF exception found" )
2539 main.log.error( self.name + ": " + self.handle.before )
2540 main.cleanup()
2541 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002542 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002543 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002544 main.cleanup()
2545 main.exit()
2546
kelvin-onlabd3b64892015-01-20 13:26:24 -08002547 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002548 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002549 Use 'devices' function to obtain list of all devices
2550 and parse the result to obtain a list of all device
2551 id's. Returns this list. Returns empty list if no
2552 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002553 List is ordered sequentially
2554
andrewonlab3e15ead2014-10-15 14:21:34 -04002555 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002556 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002557 the ids. By obtaining the list of device ids on the fly,
2558 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002559 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002560 try:
kelvin8ec71442015-01-15 16:57:00 -08002561 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002562 devicesStr = self.devices( jsonFormat=False )
2563 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002564
kelvin-onlabd3b64892015-01-20 13:26:24 -08002565 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002566 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 return idList
kelvin8ec71442015-01-15 16:57:00 -08002568
2569 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002570 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002571 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002573 # Split list further into arguments before and after string
2574 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002575 # append to idList
2576 for arg in tempList:
2577 idList.append( arg.split( "id=" )[ 1 ] )
2578 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002579
Jon Halld4d4b372015-01-28 16:02:41 -08002580 except TypeError:
2581 main.log.exception( self.name + ": Object not as expected" )
2582 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002584 main.log.error( self.name + ": EOF exception found" )
2585 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002586 main.cleanup()
2587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002588 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002589 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002590 main.cleanup()
2591 main.exit()
2592
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002594 """
andrewonlab7c211572014-10-15 16:45:20 -04002595 Uses 'nodes' function to obtain list of all nodes
2596 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002597 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002598 Returns:
2599 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002600 """
andrewonlab7c211572014-10-15 16:45:20 -04002601 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002602 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002604 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002605 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002606 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002607 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002609 nodesJson = json.loads( nodesStr )
2610 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002611 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002612 except ( TypeError, ValueError ):
2613 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002614 return None
andrewonlab7c211572014-10-15 16:45:20 -04002615 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002616 main.log.error( self.name + ": EOF exception found" )
2617 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002618 main.cleanup()
2619 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002620 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002621 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002622 main.cleanup()
2623 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002624
kelvin-onlabd3b64892015-01-20 13:26:24 -08002625 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002626 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002627 Return the first device from the devices api whose 'id' contains 'dpid'
2628 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002629 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002630 try:
kelvin8ec71442015-01-15 16:57:00 -08002631 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002632 return None
2633 else:
kelvin8ec71442015-01-15 16:57:00 -08002634 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002635 rawDevices = self.devices()
2636 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002637 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002638 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002639 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2640 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002641 return device
2642 return None
Jon Hallc6793552016-01-19 14:18:37 -08002643 except ( TypeError, ValueError ):
2644 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002645 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002649 main.cleanup()
2650 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002651 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002652 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002653 main.cleanup()
2654 main.exit()
2655
You Wang24139872016-05-03 11:48:47 -07002656 def getTopology( self, topologyOutput ):
2657 """
2658 Definition:
2659 Loads a json topology output
2660 Return:
2661 topology = current ONOS topology
2662 """
2663 import json
2664 try:
2665 # either onos:topology or 'topology' will work in CLI
2666 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002667 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002668 return topology
2669 except pexpect.EOF:
2670 main.log.error( self.name + ": EOF exception found" )
2671 main.log.error( self.name + ": " + self.handle.before )
2672 main.cleanup()
2673 main.exit()
2674 except Exception:
2675 main.log.exception( self.name + ": Uncaught exception!" )
2676 main.cleanup()
2677 main.exit()
2678
2679 def checkStatus(
2680 self,
2681 topologyResult,
2682 numoswitch,
2683 numolink,
2684 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002685 """
Jon Hallefbd9792015-03-05 16:11:36 -08002686 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002687 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002688 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002689
You Wang24139872016-05-03 11:48:47 -07002690 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002691 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002692 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002693 logLevel = level to log to.
2694 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002695
Jon Hallefbd9792015-03-05 16:11:36 -08002696 Returns: main.TRUE if the number of switches and links are correct,
2697 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002698 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002699 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002700 try:
You Wang24139872016-05-03 11:48:47 -07002701 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002702 if topology == {}:
2703 return main.ERROR
2704 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002705 # Is the number of switches is what we expected
2706 devices = topology.get( 'devices', False )
2707 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002708 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002709 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002711 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002713 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002714 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002715 output = output + "The number of links and switches match "\
2716 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002717 result = main.TRUE
2718 else:
You Wang24139872016-05-03 11:48:47 -07002719 output = output + \
2720 "The number of links and switches does not match " + \
2721 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002722 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002723 output = output + "\n ONOS sees %i devices" % int( devices )
2724 output = output + " (%i expected) " % int( numoswitch )
2725 output = output + "and %i links " % int( links )
2726 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002727 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002728 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002729 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002730 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002731 else:
You Wang24139872016-05-03 11:48:47 -07002732 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002733 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002734 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002735 main.log.error( self.name + ": EOF exception found" )
2736 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002737 main.cleanup()
2738 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002739 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002740 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002741 main.cleanup()
2742 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002743
kelvin-onlabd3b64892015-01-20 13:26:24 -08002744 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002745 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002746 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 deviceId must be the id of a device as seen in the onos devices command
2748 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002749 role must be either master, standby, or none
2750
Jon Halle3f39ff2015-01-13 11:50:53 -08002751 Returns:
2752 main.TRUE or main.FALSE based on argument verification and
2753 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002754 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002755 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002756 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002757 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002758 cmdStr = "device-role " +\
2759 str( deviceId ) + " " +\
2760 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002761 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002763 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002764 if re.search( "Error", handle ):
2765 # end color output to escape any colours
2766 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002767 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002768 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002769 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002770 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002771 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002772 main.log.error( "Invalid 'role' given to device_role(). " +
2773 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002774 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002775 except AssertionError:
2776 main.log.exception( "" )
2777 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002784 main.cleanup()
2785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002787 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002788 main.cleanup()
2789 main.exit()
2790
kelvin-onlabd3b64892015-01-20 13:26:24 -08002791 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002792 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002793 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002794 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002795 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002796 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002797 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002798 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002799 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002800 cmdStr += " -j"
2801 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002802 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002803 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002804 except AssertionError:
2805 main.log.exception( "" )
2806 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002807 except TypeError:
2808 main.log.exception( self.name + ": Object not as expected" )
2809 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002810 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002811 main.log.error( self.name + ": EOF exception found" )
2812 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002813 main.cleanup()
2814 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002815 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002816 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002817 main.cleanup()
2818 main.exit()
2819
kelvin-onlabd3b64892015-01-20 13:26:24 -08002820 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002821 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002822 CLI command to get the current leader for the Election test application
2823 NOTE: Requires installation of the onos-app-election feature
2824 Returns: Node IP of the leader if one exists
2825 None if none exists
2826 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002827 """
Jon Hall94fd0472014-12-08 11:52:42 -08002828 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 cmdStr = "election-test-leader"
2830 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002831 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002832 # Leader
2833 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002834 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002835 nodeSearch = re.search( leaderPattern, response )
2836 if nodeSearch:
2837 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002838 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002839 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002840 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002841 # no leader
2842 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002843 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002844 nullSearch = re.search( nullPattern, response )
2845 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002846 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002847 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002848 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002849 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002850 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002851 if re.search( errorPattern, response ):
2852 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002853 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002854 return main.FALSE
2855 else:
Jon Hall390696c2015-05-05 17:13:41 -07002856 main.log.error( "Error in electionTestLeader on " + self.name +
2857 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002858 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002859 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002860 except AssertionError:
2861 main.log.exception( "" )
2862 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002863 except TypeError:
2864 main.log.exception( self.name + ": Object not as expected" )
2865 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002867 main.log.error( self.name + ": EOF exception found" )
2868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002869 main.cleanup()
2870 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002871 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002872 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002873 main.cleanup()
2874 main.exit()
2875
kelvin-onlabd3b64892015-01-20 13:26:24 -08002876 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002877 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002878 CLI command to run for leadership of the Election test application.
2879 NOTE: Requires installation of the onos-app-election feature
2880 Returns: Main.TRUE on success
2881 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002882 """
Jon Hall94fd0472014-12-08 11:52:42 -08002883 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002884 cmdStr = "election-test-run"
2885 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002886 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002887 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002888 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002889 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002890 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002891 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002892 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002893 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002894 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002896 errorPattern = "Command\snot\sfound"
2897 if re.search( errorPattern, response ):
2898 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002899 return main.FALSE
2900 else:
Jon Hall390696c2015-05-05 17:13:41 -07002901 main.log.error( "Error in electionTestRun on " + self.name +
2902 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002903 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002904 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002905 except AssertionError:
2906 main.log.exception( "" )
2907 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002908 except TypeError:
2909 main.log.exception( self.name + ": Object not as expected" )
2910 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002911 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002912 main.log.error( self.name + ": EOF exception found" )
2913 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002914 main.cleanup()
2915 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002916 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002917 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002918 main.cleanup()
2919 main.exit()
2920
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002922 """
Jon Hall94fd0472014-12-08 11:52:42 -08002923 * CLI command to withdraw the local node from leadership election for
2924 * the Election test application.
2925 #NOTE: Requires installation of the onos-app-election feature
2926 Returns: Main.TRUE on success
2927 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002928 """
Jon Hall94fd0472014-12-08 11:52:42 -08002929 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002930 cmdStr = "election-test-withdraw"
2931 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002932 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002933 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002934 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002935 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002936 if re.search( successPattern, response ):
2937 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002938 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002939 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002940 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002941 errorPattern = "Command\snot\sfound"
2942 if re.search( errorPattern, response ):
2943 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002944 return main.FALSE
2945 else:
Jon Hall390696c2015-05-05 17:13:41 -07002946 main.log.error( "Error in electionTestWithdraw on " +
2947 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002949 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002950 except AssertionError:
2951 main.log.exception( "" )
2952 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002953 except TypeError:
2954 main.log.exception( self.name + ": Object not as expected" )
2955 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002956 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002957 main.log.error( self.name + ": EOF exception found" )
2958 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002959 main.cleanup()
2960 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002961 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002962 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002963 main.cleanup()
2964 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002965
kelvin8ec71442015-01-15 16:57:00 -08002966 def getDevicePortsEnabledCount( self, dpid ):
2967 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002968 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002969 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002970 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002971 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002972 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2973 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002974 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002975 if re.search( "No such device", output ):
2976 main.log.error( "Error in getting ports" )
2977 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002978 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002979 return output
Jon Hallc6793552016-01-19 14:18:37 -08002980 except AssertionError:
2981 main.log.exception( "" )
2982 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002983 except TypeError:
2984 main.log.exception( self.name + ": Object not as expected" )
2985 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002987 main.log.error( self.name + ": EOF exception found" )
2988 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002989 main.cleanup()
2990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002992 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002993 main.cleanup()
2994 main.exit()
2995
kelvin8ec71442015-01-15 16:57:00 -08002996 def getDeviceLinksActiveCount( self, dpid ):
2997 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002998 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002999 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003000 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003001 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003002 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3003 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003004 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003006 main.log.error( "Error in getting ports " )
3007 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003008 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003009 return output
Jon Hallc6793552016-01-19 14:18:37 -08003010 except AssertionError:
3011 main.log.exception( "" )
3012 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003013 except TypeError:
3014 main.log.exception( self.name + ": Object not as expected" )
3015 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003016 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003017 main.log.error( self.name + ": EOF exception found" )
3018 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003019 main.cleanup()
3020 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003021 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003022 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003023 main.cleanup()
3024 main.exit()
3025
kelvin8ec71442015-01-15 16:57:00 -08003026 def getAllIntentIds( self ):
3027 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003028 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003029 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003030 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003031 cmdStr = "onos:intents | grep id="
3032 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003033 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003034 if re.search( "Error", output ):
3035 main.log.error( "Error in getting ports" )
3036 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003037 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003038 return output
Jon Hallc6793552016-01-19 14:18:37 -08003039 except AssertionError:
3040 main.log.exception( "" )
3041 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003042 except TypeError:
3043 main.log.exception( self.name + ": Object not as expected" )
3044 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003045 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003046 main.log.error( self.name + ": EOF exception found" )
3047 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003048 main.cleanup()
3049 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003050 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003051 main.log.exception( self.name + ": Uncaught exception!" )
3052 main.cleanup()
3053 main.exit()
3054
Jon Hall73509952015-02-24 16:42:56 -08003055 def intentSummary( self ):
3056 """
Jon Hallefbd9792015-03-05 16:11:36 -08003057 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003058 """
3059 try:
3060 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003061 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003062 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003063 states.append( intent.get( 'state', None ) )
3064 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003065 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003066 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003067 except ( TypeError, ValueError ):
3068 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003069 return None
3070 except pexpect.EOF:
3071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
3073 main.cleanup()
3074 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003075 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003076 main.log.exception( self.name + ": Uncaught exception!" )
3077 main.cleanup()
3078 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003079
Jon Hall61282e32015-03-19 11:34:11 -07003080 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003081 """
3082 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003083 Optional argument:
3084 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003085 """
Jon Hall63604932015-02-26 17:09:50 -08003086 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003087 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003088 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003089 cmdStr += " -j"
3090 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003091 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003092 return output
Jon Hallc6793552016-01-19 14:18:37 -08003093 except AssertionError:
3094 main.log.exception( "" )
3095 return None
Jon Hall63604932015-02-26 17:09:50 -08003096 except TypeError:
3097 main.log.exception( self.name + ": Object not as expected" )
3098 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003099 except pexpect.EOF:
3100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
3102 main.cleanup()
3103 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003104 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003105 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003106 main.cleanup()
3107 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003108
acsmarsa4a4d1e2015-07-10 16:01:24 -07003109 def leaderCandidates( self, jsonFormat=True ):
3110 """
3111 Returns the output of the leaders -c command.
3112 Optional argument:
3113 * jsonFormat - boolean indicating if you want output in json
3114 """
3115 try:
3116 cmdStr = "onos:leaders -c"
3117 if jsonFormat:
3118 cmdStr += " -j"
3119 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003120 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003121 return output
Jon Hallc6793552016-01-19 14:18:37 -08003122 except AssertionError:
3123 main.log.exception( "" )
3124 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003125 except TypeError:
3126 main.log.exception( self.name + ": Object not as expected" )
3127 return None
3128 except pexpect.EOF:
3129 main.log.error( self.name + ": EOF exception found" )
3130 main.log.error( self.name + ": " + self.handle.before )
3131 main.cleanup()
3132 main.exit()
3133 except Exception:
3134 main.log.exception( self.name + ": Uncaught exception!" )
3135 main.cleanup()
3136 main.exit()
3137
Jon Hallc6793552016-01-19 14:18:37 -08003138 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003139 """
3140 Returns a list in format [leader,candidate1,candidate2,...] for a given
3141 topic parameter and an empty list if the topic doesn't exist
3142 If no leader is elected leader in the returned list will be "none"
3143 Returns None if there is a type error processing the json object
3144 """
3145 try:
Jon Hall6e709752016-02-01 13:38:46 -08003146 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003147 rawOutput = self.sendline( cmdStr )
3148 assert "Command not found:" not in rawOutput, rawOutput
3149 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003150 results = []
3151 for dict in output:
3152 if dict["topic"] == topic:
3153 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003154 candidates = re.split( ", ", dict["candidates"][1:-1] )
3155 results.append( leader )
3156 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003157 return results
Jon Hallc6793552016-01-19 14:18:37 -08003158 except AssertionError:
3159 main.log.exception( "" )
3160 return None
3161 except ( TypeError, ValueError ):
3162 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003163 return None
3164 except pexpect.EOF:
3165 main.log.error( self.name + ": EOF exception found" )
3166 main.log.error( self.name + ": " + self.handle.before )
3167 main.cleanup()
3168 main.exit()
3169 except Exception:
3170 main.log.exception( self.name + ": Uncaught exception!" )
3171 main.cleanup()
3172 main.exit()
3173
Jon Hall61282e32015-03-19 11:34:11 -07003174 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003175 """
3176 Returns the output of the intent Pending map.
3177 """
Jon Hall63604932015-02-26 17:09:50 -08003178 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003179 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003180 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003181 cmdStr += " -j"
3182 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003183 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003184 return output
Jon Hallc6793552016-01-19 14:18:37 -08003185 except AssertionError:
3186 main.log.exception( "" )
3187 return None
Jon Hall63604932015-02-26 17:09:50 -08003188 except TypeError:
3189 main.log.exception( self.name + ": Object not as expected" )
3190 return None
3191 except pexpect.EOF:
3192 main.log.error( self.name + ": EOF exception found" )
3193 main.log.error( self.name + ": " + self.handle.before )
3194 main.cleanup()
3195 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003196 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003197 main.log.exception( self.name + ": Uncaught exception!" )
3198 main.cleanup()
3199 main.exit()
3200
Jon Hall61282e32015-03-19 11:34:11 -07003201 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003202 """
3203 Returns the output of the raft partitions command for ONOS.
3204 """
Jon Hall61282e32015-03-19 11:34:11 -07003205 # Sample JSON
3206 # {
3207 # "leader": "tcp://10.128.30.11:7238",
3208 # "members": [
3209 # "tcp://10.128.30.11:7238",
3210 # "tcp://10.128.30.17:7238",
3211 # "tcp://10.128.30.13:7238",
3212 # ],
3213 # "name": "p1",
3214 # "term": 3
3215 # },
Jon Hall63604932015-02-26 17:09:50 -08003216 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003217 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003218 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003219 cmdStr += " -j"
3220 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003221 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003222 return output
Jon Hallc6793552016-01-19 14:18:37 -08003223 except AssertionError:
3224 main.log.exception( "" )
3225 return None
Jon Hall63604932015-02-26 17:09:50 -08003226 except TypeError:
3227 main.log.exception( self.name + ": Object not as expected" )
3228 return None
3229 except pexpect.EOF:
3230 main.log.error( self.name + ": EOF exception found" )
3231 main.log.error( self.name + ": " + self.handle.before )
3232 main.cleanup()
3233 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003234 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003235 main.log.exception( self.name + ": Uncaught exception!" )
3236 main.cleanup()
3237 main.exit()
3238
Jon Hallbe379602015-03-24 13:39:32 -07003239 def apps( self, jsonFormat=True ):
3240 """
3241 Returns the output of the apps command for ONOS. This command lists
3242 information about installed ONOS applications
3243 """
3244 # Sample JSON object
3245 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3246 # "description":"ONOS OpenFlow protocol southbound providers",
3247 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3248 # "features":"[onos-openflow]","state":"ACTIVE"}]
3249 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003250 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003251 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003252 cmdStr += " -j"
3253 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003254 assert "Command not found:" not in output, output
3255 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003256 return output
Jon Hallbe379602015-03-24 13:39:32 -07003257 # FIXME: look at specific exceptions/Errors
3258 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003259 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003260 return None
3261 except TypeError:
3262 main.log.exception( self.name + ": Object not as expected" )
3263 return None
3264 except pexpect.EOF:
3265 main.log.error( self.name + ": EOF exception found" )
3266 main.log.error( self.name + ": " + self.handle.before )
3267 main.cleanup()
3268 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003269 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003270 main.log.exception( self.name + ": Uncaught exception!" )
3271 main.cleanup()
3272 main.exit()
3273
Jon Hall146f1522015-03-24 15:33:24 -07003274 def appStatus( self, appName ):
3275 """
3276 Uses the onos:apps cli command to return the status of an application.
3277 Returns:
3278 "ACTIVE" - If app is installed and activated
3279 "INSTALLED" - If app is installed and deactivated
3280 "UNINSTALLED" - If app is not installed
3281 None - on error
3282 """
Jon Hall146f1522015-03-24 15:33:24 -07003283 try:
3284 if not isinstance( appName, types.StringType ):
3285 main.log.error( self.name + ".appStatus(): appName must be" +
3286 " a string" )
3287 return None
3288 output = self.apps( jsonFormat=True )
3289 appsJson = json.loads( output )
3290 state = None
3291 for app in appsJson:
3292 if appName == app.get('name'):
3293 state = app.get('state')
3294 break
3295 if state == "ACTIVE" or state == "INSTALLED":
3296 return state
3297 elif state is None:
3298 return "UNINSTALLED"
3299 elif state:
3300 main.log.error( "Unexpected state from 'onos:apps': " +
3301 str( state ) )
3302 return state
Jon Hallc6793552016-01-19 14:18:37 -08003303 except ( TypeError, ValueError ):
3304 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003305 return None
3306 except pexpect.EOF:
3307 main.log.error( self.name + ": EOF exception found" )
3308 main.log.error( self.name + ": " + self.handle.before )
3309 main.cleanup()
3310 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003311 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003312 main.log.exception( self.name + ": Uncaught exception!" )
3313 main.cleanup()
3314 main.exit()
3315
Jon Hallbe379602015-03-24 13:39:32 -07003316 def app( self, appName, option ):
3317 """
3318 Interacts with the app command for ONOS. This command manages
3319 application inventory.
3320 """
Jon Hallbe379602015-03-24 13:39:32 -07003321 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003322 # Validate argument types
3323 valid = True
3324 if not isinstance( appName, types.StringType ):
3325 main.log.error( self.name + ".app(): appName must be a " +
3326 "string" )
3327 valid = False
3328 if not isinstance( option, types.StringType ):
3329 main.log.error( self.name + ".app(): option must be a string" )
3330 valid = False
3331 if not valid:
3332 return main.FALSE
3333 # Validate Option
3334 option = option.lower()
3335 # NOTE: Install may become a valid option
3336 if option == "activate":
3337 pass
3338 elif option == "deactivate":
3339 pass
3340 elif option == "uninstall":
3341 pass
3342 else:
3343 # Invalid option
3344 main.log.error( "The ONOS app command argument only takes " +
3345 "the values: (activate|deactivate|uninstall)" +
3346 "; was given '" + option + "'")
3347 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003348 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003349 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003350 if "Error executing command" in output:
3351 main.log.error( "Error in processing onos:app command: " +
3352 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003353 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003354 elif "No such application" in output:
3355 main.log.error( "The application '" + appName +
3356 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003357 return main.FALSE
3358 elif "Command not found:" in output:
3359 main.log.error( "Error in processing onos:app command: " +
3360 str( output ) )
3361 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003362 elif "Unsupported command:" in output:
3363 main.log.error( "Incorrect command given to 'app': " +
3364 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003365 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003366 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003367 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003368 return main.TRUE
3369 except TypeError:
3370 main.log.exception( self.name + ": Object not as expected" )
3371 return main.ERROR
3372 except pexpect.EOF:
3373 main.log.error( self.name + ": EOF exception found" )
3374 main.log.error( self.name + ": " + self.handle.before )
3375 main.cleanup()
3376 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003377 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003378 main.log.exception( self.name + ": Uncaught exception!" )
3379 main.cleanup()
3380 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003381
Jon Hallbd16b922015-03-26 17:53:15 -07003382 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003383 """
3384 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003385 appName is the hierarchical app name, not the feature name
3386 If check is True, method will check the status of the app after the
3387 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003388 Returns main.TRUE if the command was successfully sent
3389 main.FALSE if the cli responded with an error or given
3390 incorrect input
3391 """
3392 try:
3393 if not isinstance( appName, types.StringType ):
3394 main.log.error( self.name + ".activateApp(): appName must be" +
3395 " a string" )
3396 return main.FALSE
3397 status = self.appStatus( appName )
3398 if status == "INSTALLED":
3399 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003400 if check and response == main.TRUE:
3401 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003402 status = self.appStatus( appName )
3403 if status == "ACTIVE":
3404 return main.TRUE
3405 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003406 main.log.debug( "The state of application " +
3407 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003408 time.sleep( 1 )
3409 return main.FALSE
3410 else: # not 'check' or command didn't succeed
3411 return response
Jon Hall146f1522015-03-24 15:33:24 -07003412 elif status == "ACTIVE":
3413 return main.TRUE
3414 elif status == "UNINSTALLED":
3415 main.log.error( self.name + ": Tried to activate the " +
3416 "application '" + appName + "' which is not " +
3417 "installed." )
3418 else:
3419 main.log.error( "Unexpected return value from appStatus: " +
3420 str( status ) )
3421 return main.ERROR
3422 except TypeError:
3423 main.log.exception( self.name + ": Object not as expected" )
3424 return main.ERROR
3425 except pexpect.EOF:
3426 main.log.error( self.name + ": EOF exception found" )
3427 main.log.error( self.name + ": " + self.handle.before )
3428 main.cleanup()
3429 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003430 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003431 main.log.exception( self.name + ": Uncaught exception!" )
3432 main.cleanup()
3433 main.exit()
3434
Jon Hallbd16b922015-03-26 17:53:15 -07003435 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003436 """
3437 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003438 appName is the hierarchical app name, not the feature name
3439 If check is True, method will check the status of the app after the
3440 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003441 Returns main.TRUE if the command was successfully sent
3442 main.FALSE if the cli responded with an error or given
3443 incorrect input
3444 """
3445 try:
3446 if not isinstance( appName, types.StringType ):
3447 main.log.error( self.name + ".deactivateApp(): appName must " +
3448 "be a string" )
3449 return main.FALSE
3450 status = self.appStatus( appName )
3451 if status == "INSTALLED":
3452 return main.TRUE
3453 elif status == "ACTIVE":
3454 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003455 if check and response == main.TRUE:
3456 for i in range(10): # try 10 times then give up
3457 status = self.appStatus( appName )
3458 if status == "INSTALLED":
3459 return main.TRUE
3460 else:
3461 time.sleep( 1 )
3462 return main.FALSE
3463 else: # not check or command didn't succeed
3464 return response
Jon Hall146f1522015-03-24 15:33:24 -07003465 elif status == "UNINSTALLED":
3466 main.log.warn( self.name + ": Tried to deactivate the " +
3467 "application '" + appName + "' which is not " +
3468 "installed." )
3469 return main.TRUE
3470 else:
3471 main.log.error( "Unexpected return value from appStatus: " +
3472 str( status ) )
3473 return main.ERROR
3474 except TypeError:
3475 main.log.exception( self.name + ": Object not as expected" )
3476 return main.ERROR
3477 except pexpect.EOF:
3478 main.log.error( self.name + ": EOF exception found" )
3479 main.log.error( self.name + ": " + self.handle.before )
3480 main.cleanup()
3481 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003482 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003483 main.log.exception( self.name + ": Uncaught exception!" )
3484 main.cleanup()
3485 main.exit()
3486
Jon Hallbd16b922015-03-26 17:53:15 -07003487 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003488 """
3489 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003490 appName is the hierarchical app name, not the feature name
3491 If check is True, method will check the status of the app after the
3492 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003493 Returns main.TRUE if the command was successfully sent
3494 main.FALSE if the cli responded with an error or given
3495 incorrect input
3496 """
3497 # TODO: check with Thomas about the state machine for apps
3498 try:
3499 if not isinstance( appName, types.StringType ):
3500 main.log.error( self.name + ".uninstallApp(): appName must " +
3501 "be a string" )
3502 return main.FALSE
3503 status = self.appStatus( appName )
3504 if status == "INSTALLED":
3505 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003506 if check and response == main.TRUE:
3507 for i in range(10): # try 10 times then give up
3508 status = self.appStatus( appName )
3509 if status == "UNINSTALLED":
3510 return main.TRUE
3511 else:
3512 time.sleep( 1 )
3513 return main.FALSE
3514 else: # not check or command didn't succeed
3515 return response
Jon Hall146f1522015-03-24 15:33:24 -07003516 elif status == "ACTIVE":
3517 main.log.warn( self.name + ": Tried to uninstall the " +
3518 "application '" + appName + "' which is " +
3519 "currently active." )
3520 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003521 if check and response == main.TRUE:
3522 for i in range(10): # try 10 times then give up
3523 status = self.appStatus( appName )
3524 if status == "UNINSTALLED":
3525 return main.TRUE
3526 else:
3527 time.sleep( 1 )
3528 return main.FALSE
3529 else: # not check or command didn't succeed
3530 return response
Jon Hall146f1522015-03-24 15:33:24 -07003531 elif status == "UNINSTALLED":
3532 return main.TRUE
3533 else:
3534 main.log.error( "Unexpected return value from appStatus: " +
3535 str( status ) )
3536 return main.ERROR
3537 except TypeError:
3538 main.log.exception( self.name + ": Object not as expected" )
3539 return main.ERROR
3540 except pexpect.EOF:
3541 main.log.error( self.name + ": EOF exception found" )
3542 main.log.error( self.name + ": " + self.handle.before )
3543 main.cleanup()
3544 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003545 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003546 main.log.exception( self.name + ": Uncaught exception!" )
3547 main.cleanup()
3548 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003549
3550 def appIDs( self, jsonFormat=True ):
3551 """
3552 Show the mappings between app id and app names given by the 'app-ids'
3553 cli command
3554 """
3555 try:
3556 cmdStr = "app-ids"
3557 if jsonFormat:
3558 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003559 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003560 assert "Command not found:" not in output, output
3561 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003562 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003563 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003564 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003565 return None
3566 except TypeError:
3567 main.log.exception( self.name + ": Object not as expected" )
3568 return None
3569 except pexpect.EOF:
3570 main.log.error( self.name + ": EOF exception found" )
3571 main.log.error( self.name + ": " + self.handle.before )
3572 main.cleanup()
3573 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003574 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003575 main.log.exception( self.name + ": Uncaught exception!" )
3576 main.cleanup()
3577 main.exit()
3578
3579 def appToIDCheck( self ):
3580 """
3581 This method will check that each application's ID listed in 'apps' is
3582 the same as the ID listed in 'app-ids'. The check will also check that
3583 there are no duplicate IDs issued. Note that an app ID should be
3584 a globaly unique numerical identifier for app/app-like features. Once
3585 an ID is registered, the ID is never freed up so that if an app is
3586 reinstalled it will have the same ID.
3587
3588 Returns: main.TRUE if the check passes and
3589 main.FALSE if the check fails or
3590 main.ERROR if there is some error in processing the test
3591 """
3592 try:
Jon Hall390696c2015-05-05 17:13:41 -07003593 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003594 rawJson = self.appIDs( jsonFormat=True )
3595 if rawJson:
3596 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003597 else:
Jon Hallc6793552016-01-19 14:18:37 -08003598 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003599 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003600 rawJson = self.apps( jsonFormat=True )
3601 if rawJson:
3602 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003603 else:
Jon Hallc6793552016-01-19 14:18:37 -08003604 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003605 bail = True
3606 if bail:
3607 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003608 result = main.TRUE
3609 for app in apps:
3610 appID = app.get( 'id' )
3611 if appID is None:
3612 main.log.error( "Error parsing app: " + str( app ) )
3613 result = main.FALSE
3614 appName = app.get( 'name' )
3615 if appName is None:
3616 main.log.error( "Error parsing app: " + str( app ) )
3617 result = main.FALSE
3618 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003619 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003620 # main.log.debug( "Comparing " + str( app ) + " to " +
3621 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003622 if not current: # if ids doesn't have this id
3623 result = main.FALSE
3624 main.log.error( "'app-ids' does not have the ID for " +
3625 str( appName ) + " that apps does." )
3626 elif len( current ) > 1:
3627 # there is more than one app with this ID
3628 result = main.FALSE
3629 # We will log this later in the method
3630 elif not current[0][ 'name' ] == appName:
3631 currentName = current[0][ 'name' ]
3632 result = main.FALSE
3633 main.log.error( "'app-ids' has " + str( currentName ) +
3634 " registered under id:" + str( appID ) +
3635 " but 'apps' has " + str( appName ) )
3636 else:
3637 pass # id and name match!
3638 # now make sure that app-ids has no duplicates
3639 idsList = []
3640 namesList = []
3641 for item in ids:
3642 idsList.append( item[ 'id' ] )
3643 namesList.append( item[ 'name' ] )
3644 if len( idsList ) != len( set( idsList ) ) or\
3645 len( namesList ) != len( set( namesList ) ):
3646 main.log.error( "'app-ids' has some duplicate entries: \n"
3647 + json.dumps( ids,
3648 sort_keys=True,
3649 indent=4,
3650 separators=( ',', ': ' ) ) )
3651 result = main.FALSE
3652 return result
Jon Hallc6793552016-01-19 14:18:37 -08003653 except ( TypeError, ValueError ):
3654 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003655 return main.ERROR
3656 except pexpect.EOF:
3657 main.log.error( self.name + ": EOF exception found" )
3658 main.log.error( self.name + ": " + self.handle.before )
3659 main.cleanup()
3660 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003661 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003662 main.log.exception( self.name + ": Uncaught exception!" )
3663 main.cleanup()
3664 main.exit()
3665
Jon Hallfb760a02015-04-13 15:35:03 -07003666 def getCfg( self, component=None, propName=None, short=False,
3667 jsonFormat=True ):
3668 """
3669 Get configuration settings from onos cli
3670 Optional arguments:
3671 component - Optionally only list configurations for a specific
3672 component. If None, all components with configurations
3673 are displayed. Case Sensitive string.
3674 propName - If component is specified, propName option will show
3675 only this specific configuration from that component.
3676 Case Sensitive string.
3677 jsonFormat - Returns output as json. Note that this will override
3678 the short option
3679 short - Short, less verbose, version of configurations.
3680 This is overridden by the json option
3681 returns:
3682 Output from cli as a string or None on error
3683 """
3684 try:
3685 baseStr = "cfg"
3686 cmdStr = " get"
3687 componentStr = ""
3688 if component:
3689 componentStr += " " + component
3690 if propName:
3691 componentStr += " " + propName
3692 if jsonFormat:
3693 baseStr += " -j"
3694 elif short:
3695 baseStr += " -s"
3696 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003697 assert "Command not found:" not in output, output
3698 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003699 return output
3700 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003701 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003702 return None
3703 except TypeError:
3704 main.log.exception( self.name + ": Object not as expected" )
3705 return None
3706 except pexpect.EOF:
3707 main.log.error( self.name + ": EOF exception found" )
3708 main.log.error( self.name + ": " + self.handle.before )
3709 main.cleanup()
3710 main.exit()
3711 except Exception:
3712 main.log.exception( self.name + ": Uncaught exception!" )
3713 main.cleanup()
3714 main.exit()
3715
3716 def setCfg( self, component, propName, value=None, check=True ):
3717 """
3718 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003719 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003720 component - The case sensitive name of the component whose
3721 property is to be set
3722 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003723 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003724 value - The value to set the property to. If None, will unset the
3725 property and revert it to it's default value(if applicable)
3726 check - Boolean, Check whether the option was successfully set this
3727 only applies when a value is given.
3728 returns:
3729 main.TRUE on success or main.FALSE on failure. If check is False,
3730 will return main.TRUE unless there is an error
3731 """
3732 try:
3733 baseStr = "cfg"
3734 cmdStr = " set " + str( component ) + " " + str( propName )
3735 if value is not None:
3736 cmdStr += " " + str( value )
3737 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003738 assert "Command not found:" not in output, output
3739 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003740 if value and check:
3741 results = self.getCfg( component=str( component ),
3742 propName=str( propName ),
3743 jsonFormat=True )
3744 # Check if current value is what we just set
3745 try:
3746 jsonOutput = json.loads( results )
3747 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003748 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003749 main.log.exception( "Error parsing cfg output" )
3750 main.log.error( "output:" + repr( results ) )
3751 return main.FALSE
3752 if current == str( value ):
3753 return main.TRUE
3754 return main.FALSE
3755 return main.TRUE
3756 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003757 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003758 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003759 except ( TypeError, ValueError ):
3760 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003761 return main.FALSE
3762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
3765 main.cleanup()
3766 main.exit()
3767 except Exception:
3768 main.log.exception( self.name + ": Uncaught exception!" )
3769 main.cleanup()
3770 main.exit()
3771
Jon Hall390696c2015-05-05 17:13:41 -07003772 def setTestAdd( self, setName, values ):
3773 """
3774 CLI command to add elements to a distributed set.
3775 Arguments:
3776 setName - The name of the set to add to.
3777 values - The value(s) to add to the set, space seperated.
3778 Example usages:
3779 setTestAdd( "set1", "a b c" )
3780 setTestAdd( "set2", "1" )
3781 returns:
3782 main.TRUE on success OR
3783 main.FALSE if elements were already in the set OR
3784 main.ERROR on error
3785 """
3786 try:
3787 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3788 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003789 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003790 try:
3791 # TODO: Maybe make this less hardcoded
3792 # ConsistentMap Exceptions
3793 assert "org.onosproject.store.service" not in output
3794 # Node not leader
3795 assert "java.lang.IllegalStateException" not in output
3796 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003797 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003798 "command: " + str( output ) )
3799 retryTime = 30 # Conservative time, given by Madan
3800 main.log.info( "Waiting " + str( retryTime ) +
3801 "seconds before retrying." )
3802 time.sleep( retryTime ) # Due to change in mastership
3803 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003804 assert "Error executing command" not in output
3805 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3806 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3807 main.log.info( self.name + ": " + output )
3808 if re.search( positiveMatch, output):
3809 return main.TRUE
3810 elif re.search( negativeMatch, output):
3811 return main.FALSE
3812 else:
3813 main.log.error( self.name + ": setTestAdd did not" +
3814 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003815 main.log.debug( self.name + " actual: " + repr( output ) )
3816 return main.ERROR
3817 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003818 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003819 return main.ERROR
3820 except TypeError:
3821 main.log.exception( self.name + ": Object not as expected" )
3822 return main.ERROR
3823 except pexpect.EOF:
3824 main.log.error( self.name + ": EOF exception found" )
3825 main.log.error( self.name + ": " + self.handle.before )
3826 main.cleanup()
3827 main.exit()
3828 except Exception:
3829 main.log.exception( self.name + ": Uncaught exception!" )
3830 main.cleanup()
3831 main.exit()
3832
3833 def setTestRemove( self, setName, values, clear=False, retain=False ):
3834 """
3835 CLI command to remove elements from a distributed set.
3836 Required arguments:
3837 setName - The name of the set to remove from.
3838 values - The value(s) to remove from the set, space seperated.
3839 Optional arguments:
3840 clear - Clear all elements from the set
3841 retain - Retain only the given values. (intersection of the
3842 original set and the given set)
3843 returns:
3844 main.TRUE on success OR
3845 main.FALSE if the set was not changed OR
3846 main.ERROR on error
3847 """
3848 try:
3849 cmdStr = "set-test-remove "
3850 if clear:
3851 cmdStr += "-c " + str( setName )
3852 elif retain:
3853 cmdStr += "-r " + str( setName ) + " " + str( values )
3854 else:
3855 cmdStr += str( setName ) + " " + str( values )
3856 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003857 try:
3858 # TODO: Maybe make this less hardcoded
3859 # ConsistentMap Exceptions
3860 assert "org.onosproject.store.service" not in output
3861 # Node not leader
3862 assert "java.lang.IllegalStateException" not in output
3863 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003864 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003865 "command: " + str( output ) )
3866 retryTime = 30 # Conservative time, given by Madan
3867 main.log.info( "Waiting " + str( retryTime ) +
3868 "seconds before retrying." )
3869 time.sleep( retryTime ) # Due to change in mastership
3870 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003871 assert "Command not found:" not in output, output
3872 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003873 main.log.info( self.name + ": " + output )
3874 if clear:
3875 pattern = "Set " + str( setName ) + " cleared"
3876 if re.search( pattern, output ):
3877 return main.TRUE
3878 elif retain:
3879 positivePattern = str( setName ) + " was pruned to contain " +\
3880 "only elements of set \[(.*)\]"
3881 negativePattern = str( setName ) + " was not changed by " +\
3882 "retaining only elements of the set " +\
3883 "\[(.*)\]"
3884 if re.search( positivePattern, output ):
3885 return main.TRUE
3886 elif re.search( negativePattern, output ):
3887 return main.FALSE
3888 else:
3889 positivePattern = "\[(.*)\] was removed from the set " +\
3890 str( setName )
3891 if ( len( values.split() ) == 1 ):
3892 negativePattern = "\[(.*)\] was not in set " +\
3893 str( setName )
3894 else:
3895 negativePattern = "No element of \[(.*)\] was in set " +\
3896 str( setName )
3897 if re.search( positivePattern, output ):
3898 return main.TRUE
3899 elif re.search( negativePattern, output ):
3900 return main.FALSE
3901 main.log.error( self.name + ": setTestRemove did not" +
3902 " match expected output" )
3903 main.log.debug( self.name + " expected: " + pattern )
3904 main.log.debug( self.name + " actual: " + repr( output ) )
3905 return main.ERROR
3906 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003907 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003908 return main.ERROR
3909 except TypeError:
3910 main.log.exception( self.name + ": Object not as expected" )
3911 return main.ERROR
3912 except pexpect.EOF:
3913 main.log.error( self.name + ": EOF exception found" )
3914 main.log.error( self.name + ": " + self.handle.before )
3915 main.cleanup()
3916 main.exit()
3917 except Exception:
3918 main.log.exception( self.name + ": Uncaught exception!" )
3919 main.cleanup()
3920 main.exit()
3921
3922 def setTestGet( self, setName, values="" ):
3923 """
3924 CLI command to get the elements in a distributed set.
3925 Required arguments:
3926 setName - The name of the set to remove from.
3927 Optional arguments:
3928 values - The value(s) to check if in the set, space seperated.
3929 returns:
3930 main.ERROR on error OR
3931 A list of elements in the set if no optional arguments are
3932 supplied OR
3933 A tuple containing the list then:
3934 main.FALSE if the given values are not in the set OR
3935 main.TRUE if the given values are in the set OR
3936 """
3937 try:
3938 values = str( values ).strip()
3939 setName = str( setName ).strip()
3940 length = len( values.split() )
3941 containsCheck = None
3942 # Patterns to match
3943 setPattern = "\[(.*)\]"
3944 pattern = "Items in set " + setName + ":\n" + setPattern
3945 containsTrue = "Set " + setName + " contains the value " + values
3946 containsFalse = "Set " + setName + " did not contain the value " +\
3947 values
3948 containsAllTrue = "Set " + setName + " contains the the subset " +\
3949 setPattern
3950 containsAllFalse = "Set " + setName + " did not contain the the" +\
3951 " subset " + setPattern
3952
3953 cmdStr = "set-test-get "
3954 cmdStr += setName + " " + values
3955 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003956 try:
3957 # TODO: Maybe make this less hardcoded
3958 # ConsistentMap Exceptions
3959 assert "org.onosproject.store.service" not in output
3960 # Node not leader
3961 assert "java.lang.IllegalStateException" not in output
3962 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003963 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003964 "command: " + str( output ) )
3965 retryTime = 30 # Conservative time, given by Madan
3966 main.log.info( "Waiting " + str( retryTime ) +
3967 "seconds before retrying." )
3968 time.sleep( retryTime ) # Due to change in mastership
3969 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003970 assert "Command not found:" not in output, output
3971 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003972 main.log.info( self.name + ": " + output )
3973
3974 if length == 0:
3975 match = re.search( pattern, output )
3976 else: # if given values
3977 if length == 1: # Contains output
3978 patternTrue = pattern + "\n" + containsTrue
3979 patternFalse = pattern + "\n" + containsFalse
3980 else: # ContainsAll output
3981 patternTrue = pattern + "\n" + containsAllTrue
3982 patternFalse = pattern + "\n" + containsAllFalse
3983 matchTrue = re.search( patternTrue, output )
3984 matchFalse = re.search( patternFalse, output )
3985 if matchTrue:
3986 containsCheck = main.TRUE
3987 match = matchTrue
3988 elif matchFalse:
3989 containsCheck = main.FALSE
3990 match = matchFalse
3991 else:
3992 main.log.error( self.name + " setTestGet did not match " +\
3993 "expected output" )
3994 main.log.debug( self.name + " expected: " + pattern )
3995 main.log.debug( self.name + " actual: " + repr( output ) )
3996 match = None
3997 if match:
3998 setMatch = match.group( 1 )
3999 if setMatch == '':
4000 setList = []
4001 else:
4002 setList = setMatch.split( ", " )
4003 if length > 0:
4004 return ( setList, containsCheck )
4005 else:
4006 return setList
4007 else: # no match
4008 main.log.error( self.name + ": setTestGet did not" +
4009 " match expected output" )
4010 main.log.debug( self.name + " expected: " + pattern )
4011 main.log.debug( self.name + " actual: " + repr( output ) )
4012 return main.ERROR
4013 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004014 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004015 return main.ERROR
4016 except TypeError:
4017 main.log.exception( self.name + ": Object not as expected" )
4018 return main.ERROR
4019 except pexpect.EOF:
4020 main.log.error( self.name + ": EOF exception found" )
4021 main.log.error( self.name + ": " + self.handle.before )
4022 main.cleanup()
4023 main.exit()
4024 except Exception:
4025 main.log.exception( self.name + ": Uncaught exception!" )
4026 main.cleanup()
4027 main.exit()
4028
4029 def setTestSize( self, setName ):
4030 """
4031 CLI command to get the elements in a distributed set.
4032 Required arguments:
4033 setName - The name of the set to remove from.
4034 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004035 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004036 None on error
4037 """
4038 try:
4039 # TODO: Should this check against the number of elements returned
4040 # and then return true/false based on that?
4041 setName = str( setName ).strip()
4042 # Patterns to match
4043 setPattern = "\[(.*)\]"
4044 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4045 setPattern
4046 cmdStr = "set-test-get -s "
4047 cmdStr += setName
4048 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004049 try:
4050 # TODO: Maybe make this less hardcoded
4051 # ConsistentMap Exceptions
4052 assert "org.onosproject.store.service" not in output
4053 # Node not leader
4054 assert "java.lang.IllegalStateException" not in output
4055 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004056 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004057 "command: " + str( output ) )
4058 retryTime = 30 # Conservative time, given by Madan
4059 main.log.info( "Waiting " + str( retryTime ) +
4060 "seconds before retrying." )
4061 time.sleep( retryTime ) # Due to change in mastership
4062 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004063 assert "Command not found:" not in output, output
4064 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004065 main.log.info( self.name + ": " + output )
4066 match = re.search( pattern, output )
4067 if match:
4068 setSize = int( match.group( 1 ) )
4069 setMatch = match.group( 2 )
4070 if len( setMatch.split() ) == setSize:
4071 main.log.info( "The size returned by " + self.name +
4072 " matches the number of elements in " +
4073 "the returned set" )
4074 else:
4075 main.log.error( "The size returned by " + self.name +
4076 " does not match the number of " +
4077 "elements in the returned set." )
4078 return setSize
4079 else: # no match
4080 main.log.error( self.name + ": setTestGet did not" +
4081 " match expected output" )
4082 main.log.debug( self.name + " expected: " + pattern )
4083 main.log.debug( self.name + " actual: " + repr( output ) )
4084 return None
4085 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004086 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004087 return None
Jon Hall390696c2015-05-05 17:13:41 -07004088 except TypeError:
4089 main.log.exception( self.name + ": Object not as expected" )
4090 return None
4091 except pexpect.EOF:
4092 main.log.error( self.name + ": EOF exception found" )
4093 main.log.error( self.name + ": " + self.handle.before )
4094 main.cleanup()
4095 main.exit()
4096 except Exception:
4097 main.log.exception( self.name + ": Uncaught exception!" )
4098 main.cleanup()
4099 main.exit()
4100
Jon Hall80daded2015-05-27 16:07:00 -07004101 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004102 """
4103 Command to list the various counters in the system.
4104 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004105 if jsonFormat, a string of the json object returned by the cli
4106 command
4107 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004108 None on error
4109 """
Jon Hall390696c2015-05-05 17:13:41 -07004110 try:
4111 counters = {}
4112 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004113 if jsonFormat:
4114 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004115 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004116 assert "Command not found:" not in output, output
4117 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004118 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004119 return output
Jon Hall390696c2015-05-05 17:13:41 -07004120 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004121 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004122 return None
Jon Hall390696c2015-05-05 17:13:41 -07004123 except TypeError:
4124 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004125 return None
Jon Hall390696c2015-05-05 17:13:41 -07004126 except pexpect.EOF:
4127 main.log.error( self.name + ": EOF exception found" )
4128 main.log.error( self.name + ": " + self.handle.before )
4129 main.cleanup()
4130 main.exit()
4131 except Exception:
4132 main.log.exception( self.name + ": Uncaught exception!" )
4133 main.cleanup()
4134 main.exit()
4135
Jon Hall935db192016-04-19 00:22:04 -07004136 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004137 """
Jon Halle1a3b752015-07-22 13:02:46 -07004138 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004139 Required arguments:
4140 counter - The name of the counter to increment.
4141 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004142 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004143 returns:
4144 integer value of the counter or
4145 None on Error
4146 """
4147 try:
4148 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004149 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004150 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004151 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004152 if delta != 1:
4153 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004154 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004155 try:
4156 # TODO: Maybe make this less hardcoded
4157 # ConsistentMap Exceptions
4158 assert "org.onosproject.store.service" not in output
4159 # Node not leader
4160 assert "java.lang.IllegalStateException" not in output
4161 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004162 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004163 "command: " + str( output ) )
4164 retryTime = 30 # Conservative time, given by Madan
4165 main.log.info( "Waiting " + str( retryTime ) +
4166 "seconds before retrying." )
4167 time.sleep( retryTime ) # Due to change in mastership
4168 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004169 assert "Command not found:" not in output, output
4170 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004171 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004172 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004173 match = re.search( pattern, output )
4174 if match:
4175 return int( match.group( 1 ) )
4176 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004177 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004178 " match expected output." )
4179 main.log.debug( self.name + " expected: " + pattern )
4180 main.log.debug( self.name + " actual: " + repr( output ) )
4181 return None
4182 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004183 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004184 return None
4185 except TypeError:
4186 main.log.exception( self.name + ": Object not as expected" )
4187 return None
4188 except pexpect.EOF:
4189 main.log.error( self.name + ": EOF exception found" )
4190 main.log.error( self.name + ": " + self.handle.before )
4191 main.cleanup()
4192 main.exit()
4193 except Exception:
4194 main.log.exception( self.name + ": Uncaught exception!" )
4195 main.cleanup()
4196 main.exit()
4197
Jon Hall935db192016-04-19 00:22:04 -07004198 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004199 """
4200 CLI command to get a distributed counter then add a delta to it.
4201 Required arguments:
4202 counter - The name of the counter to increment.
4203 Optional arguments:
4204 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004205 returns:
4206 integer value of the counter or
4207 None on Error
4208 """
4209 try:
4210 counter = str( counter )
4211 delta = int( delta )
4212 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004213 cmdStr += counter
4214 if delta != 1:
4215 cmdStr += " " + str( delta )
4216 output = self.sendline( cmdStr )
4217 try:
4218 # TODO: Maybe make this less hardcoded
4219 # ConsistentMap Exceptions
4220 assert "org.onosproject.store.service" not in output
4221 # Node not leader
4222 assert "java.lang.IllegalStateException" not in output
4223 except AssertionError:
4224 main.log.error( "Error in processing '" + cmdStr + "' " +
4225 "command: " + str( output ) )
4226 retryTime = 30 # Conservative time, given by Madan
4227 main.log.info( "Waiting " + str( retryTime ) +
4228 "seconds before retrying." )
4229 time.sleep( retryTime ) # Due to change in mastership
4230 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004231 assert "Command not found:" not in output, output
4232 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004233 main.log.info( self.name + ": " + output )
4234 pattern = counter + " was updated to (-?\d+)"
4235 match = re.search( pattern, output )
4236 if match:
4237 return int( match.group( 1 ) )
4238 else:
4239 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4240 " match expected output." )
4241 main.log.debug( self.name + " expected: " + pattern )
4242 main.log.debug( self.name + " actual: " + repr( output ) )
4243 return None
4244 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004245 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004246 return None
4247 except TypeError:
4248 main.log.exception( self.name + ": Object not as expected" )
4249 return None
4250 except pexpect.EOF:
4251 main.log.error( self.name + ": EOF exception found" )
4252 main.log.error( self.name + ": " + self.handle.before )
4253 main.cleanup()
4254 main.exit()
4255 except Exception:
4256 main.log.exception( self.name + ": Uncaught exception!" )
4257 main.cleanup()
4258 main.exit()
4259
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004260 def summary( self, jsonFormat=True ):
4261 """
4262 Description: Execute summary command in onos
4263 Returns: json object ( summary -j ), returns main.FALSE if there is
4264 no output
4265
4266 """
4267 try:
4268 cmdStr = "summary"
4269 if jsonFormat:
4270 cmdStr += " -j"
4271 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004272 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004273 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004274 if not handle:
4275 main.log.error( self.name + ": There is no output in " +
4276 "summary command" )
4277 return main.FALSE
4278 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004279 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004280 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004281 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004282 except TypeError:
4283 main.log.exception( self.name + ": Object not as expected" )
4284 return None
4285 except pexpect.EOF:
4286 main.log.error( self.name + ": EOF exception found" )
4287 main.log.error( self.name + ": " + self.handle.before )
4288 main.cleanup()
4289 main.exit()
4290 except Exception:
4291 main.log.exception( self.name + ": Uncaught exception!" )
4292 main.cleanup()
4293 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004294
Jon Hall935db192016-04-19 00:22:04 -07004295 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004296 """
4297 CLI command to get the value of a key in a consistent map using
4298 transactions. This a test function and can only get keys from the
4299 test map hard coded into the cli command
4300 Required arguments:
4301 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004302 returns:
4303 The string value of the key or
4304 None on Error
4305 """
4306 try:
4307 keyName = str( keyName )
4308 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004309 cmdStr += keyName
4310 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004311 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004312 try:
4313 # TODO: Maybe make this less hardcoded
4314 # ConsistentMap Exceptions
4315 assert "org.onosproject.store.service" not in output
4316 # Node not leader
4317 assert "java.lang.IllegalStateException" not in output
4318 except AssertionError:
4319 main.log.error( "Error in processing '" + cmdStr + "' " +
4320 "command: " + str( output ) )
4321 return None
4322 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4323 if "Key " + keyName + " not found." in output:
4324 return None
4325 else:
4326 match = re.search( pattern, output )
4327 if match:
4328 return match.groupdict()[ 'value' ]
4329 else:
4330 main.log.error( self.name + ": transactionlMapGet did not" +
4331 " match expected output." )
4332 main.log.debug( self.name + " expected: " + pattern )
4333 main.log.debug( self.name + " actual: " + repr( output ) )
4334 return None
Jon Hallc6793552016-01-19 14:18:37 -08004335 except AssertionError:
4336 main.log.exception( "" )
4337 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004338 except TypeError:
4339 main.log.exception( self.name + ": Object not as expected" )
4340 return None
4341 except pexpect.EOF:
4342 main.log.error( self.name + ": EOF exception found" )
4343 main.log.error( self.name + ": " + self.handle.before )
4344 main.cleanup()
4345 main.exit()
4346 except Exception:
4347 main.log.exception( self.name + ": Uncaught exception!" )
4348 main.cleanup()
4349 main.exit()
4350
Jon Hall935db192016-04-19 00:22:04 -07004351 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004352 """
4353 CLI command to put a value into 'numKeys' number of keys in a
4354 consistent map using transactions. This a test function and can only
4355 put into keys named 'Key#' of the test map hard coded into the cli command
4356 Required arguments:
4357 numKeys - Number of keys to add the value to
4358 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004359 returns:
4360 A dictionary whose keys are the name of the keys put into the map
4361 and the values of the keys are dictionaries whose key-values are
4362 'value': value put into map and optionaly
4363 'oldValue': Previous value in the key or
4364 None on Error
4365
4366 Example output
4367 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4368 'Key2': {'value': 'Testing'} }
4369 """
4370 try:
4371 numKeys = str( numKeys )
4372 value = str( value )
4373 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004374 cmdStr += numKeys + " " + value
4375 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004376 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004377 try:
4378 # TODO: Maybe make this less hardcoded
4379 # ConsistentMap Exceptions
4380 assert "org.onosproject.store.service" not in output
4381 # Node not leader
4382 assert "java.lang.IllegalStateException" not in output
4383 except AssertionError:
4384 main.log.error( "Error in processing '" + cmdStr + "' " +
4385 "command: " + str( output ) )
4386 return None
4387 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4388 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4389 results = {}
4390 for line in output.splitlines():
4391 new = re.search( newPattern, line )
4392 updated = re.search( updatedPattern, line )
4393 if new:
4394 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4395 elif updated:
4396 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004397 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004398 else:
4399 main.log.error( self.name + ": transactionlMapGet did not" +
4400 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004401 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4402 newPattern,
4403 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004404 main.log.debug( self.name + " actual: " + repr( output ) )
4405 return results
Jon Hallc6793552016-01-19 14:18:37 -08004406 except AssertionError:
4407 main.log.exception( "" )
4408 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004409 except TypeError:
4410 main.log.exception( self.name + ": Object not as expected" )
4411 return None
4412 except pexpect.EOF:
4413 main.log.error( self.name + ": EOF exception found" )
4414 main.log.error( self.name + ": " + self.handle.before )
4415 main.cleanup()
4416 main.exit()
4417 except Exception:
4418 main.log.exception( self.name + ": Uncaught exception!" )
4419 main.cleanup()
4420 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004421
acsmarsdaea66c2015-09-03 11:44:06 -07004422 def maps( self, jsonFormat=True ):
4423 """
4424 Description: Returns result of onos:maps
4425 Optional:
4426 * jsonFormat: enable json formatting of output
4427 """
4428 try:
4429 cmdStr = "maps"
4430 if jsonFormat:
4431 cmdStr += " -j"
4432 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004433 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004434 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004435 except AssertionError:
4436 main.log.exception( "" )
4437 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004438 except TypeError:
4439 main.log.exception( self.name + ": Object not as expected" )
4440 return None
4441 except pexpect.EOF:
4442 main.log.error( self.name + ": EOF exception found" )
4443 main.log.error( self.name + ": " + self.handle.before )
4444 main.cleanup()
4445 main.exit()
4446 except Exception:
4447 main.log.exception( self.name + ": Uncaught exception!" )
4448 main.cleanup()
4449 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004450
4451 def getSwController( self, uri, jsonFormat=True ):
4452 """
4453 Descrition: Gets the controller information from the device
4454 """
4455 try:
4456 cmd = "device-controllers "
4457 if jsonFormat:
4458 cmd += "-j "
4459 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004460 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004461 return response
Jon Hallc6793552016-01-19 14:18:37 -08004462 except AssertionError:
4463 main.log.exception( "" )
4464 return None
GlennRC050596c2015-11-18 17:06:41 -08004465 except TypeError:
4466 main.log.exception( self.name + ": Object not as expected" )
4467 return None
4468 except pexpect.EOF:
4469 main.log.error( self.name + ": EOF exception found" )
4470 main.log.error( self.name + ": " + self.handle.before )
4471 main.cleanup()
4472 main.exit()
4473 except Exception:
4474 main.log.exception( self.name + ": Uncaught exception!" )
4475 main.cleanup()
4476 main.exit()
4477
4478 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4479 """
4480 Descrition: sets the controller(s) for the specified device
4481
4482 Parameters:
4483 Required: uri - String: The uri of the device(switch).
4484 ip - String or List: The ip address of the controller.
4485 This parameter can be formed in a couple of different ways.
4486 VALID:
4487 10.0.0.1 - just the ip address
4488 tcp:10.0.0.1 - the protocol and the ip address
4489 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4490 so that you can add controllers with different
4491 protocols and ports
4492 INVALID:
4493 10.0.0.1:6653 - this is not supported by ONOS
4494
4495 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4496 port - The port number.
4497 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4498
4499 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4500 """
4501 try:
4502 cmd = "device-setcontrollers"
4503
4504 if jsonFormat:
4505 cmd += " -j"
4506 cmd += " " + uri
4507 if isinstance( ip, str ):
4508 ip = [ip]
4509 for item in ip:
4510 if ":" in item:
4511 sitem = item.split( ":" )
4512 if len(sitem) == 3:
4513 cmd += " " + item
4514 elif "." in sitem[1]:
4515 cmd += " {}:{}".format(item, port)
4516 else:
4517 main.log.error( "Malformed entry: " + item )
4518 raise TypeError
4519 else:
4520 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004521 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004522 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004523 if "Error" in response:
4524 main.log.error( response )
4525 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004526 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004527 except AssertionError:
4528 main.log.exception( "" )
4529 return None
GlennRC050596c2015-11-18 17:06:41 -08004530 except TypeError:
4531 main.log.exception( self.name + ": Object not as expected" )
4532 return main.FALSE
4533 except pexpect.EOF:
4534 main.log.error( self.name + ": EOF exception found" )
4535 main.log.error( self.name + ": " + self.handle.before )
4536 main.cleanup()
4537 main.exit()
4538 except Exception:
4539 main.log.exception( self.name + ": Uncaught exception!" )
4540 main.cleanup()
4541 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004542
4543 def removeDevice( self, device ):
4544 '''
4545 Description:
4546 Remove a device from ONOS by passing the uri of the device(s).
4547 Parameters:
4548 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4549 Returns:
4550 Returns main.FALSE if an exception is thrown or an error is present
4551 in the response. Otherwise, returns main.TRUE.
4552 NOTE:
4553 If a host cannot be removed, then this function will return main.FALSE
4554 '''
4555 try:
4556 if type( device ) is str:
4557 device = list( device )
4558
4559 for d in device:
4560 time.sleep( 1 )
4561 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004562 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004563 if "Error" in response:
4564 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4565 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004566 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004567 except AssertionError:
4568 main.log.exception( "" )
4569 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004570 except TypeError:
4571 main.log.exception( self.name + ": Object not as expected" )
4572 return main.FALSE
4573 except pexpect.EOF:
4574 main.log.error( self.name + ": EOF exception found" )
4575 main.log.error( self.name + ": " + self.handle.before )
4576 main.cleanup()
4577 main.exit()
4578 except Exception:
4579 main.log.exception( self.name + ": Uncaught exception!" )
4580 main.cleanup()
4581 main.exit()
4582
4583 def removeHost( self, host ):
4584 '''
4585 Description:
4586 Remove a host from ONOS by passing the id of the host(s)
4587 Parameters:
4588 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4589 Returns:
4590 Returns main.FALSE if an exception is thrown or an error is present
4591 in the response. Otherwise, returns main.TRUE.
4592 NOTE:
4593 If a host cannot be removed, then this function will return main.FALSE
4594 '''
4595 try:
4596 if type( host ) is str:
4597 host = list( host )
4598
4599 for h in host:
4600 time.sleep( 1 )
4601 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004602 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004603 if "Error" in response:
4604 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4605 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004606 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004607 except AssertionError:
4608 main.log.exception( "" )
4609 return None
GlennRC20fc6522015-12-23 23:26:57 -08004610 except TypeError:
4611 main.log.exception( self.name + ": Object not as expected" )
4612 return main.FALSE
4613 except pexpect.EOF:
4614 main.log.error( self.name + ": EOF exception found" )
4615 main.log.error( self.name + ": " + self.handle.before )
4616 main.cleanup()
4617 main.exit()
4618 except Exception:
4619 main.log.exception( self.name + ": Uncaught exception!" )
4620 main.cleanup()
4621 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004622
Jon Hallc6793552016-01-19 14:18:37 -08004623 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004624 '''
4625 Description:
4626 Bring link down or up in the null-provider.
4627 params:
4628 begin - (string) One end of a device or switch.
4629 end - (string) the other end of the device or switch
4630 returns:
4631 main.TRUE if no exceptions were thrown and no Errors are
4632 present in the resoponse. Otherwise, returns main.FALSE
4633 '''
4634 try:
Jon Hallc6793552016-01-19 14:18:37 -08004635 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004636 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004637 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004638 if "Error" in response or "Failure" in response:
4639 main.log.error( response )
4640 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004641 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004642 except AssertionError:
4643 main.log.exception( "" )
4644 return None
GlennRCed771242016-01-13 17:02:47 -08004645 except TypeError:
4646 main.log.exception( self.name + ": Object not as expected" )
4647 return main.FALSE
4648 except pexpect.EOF:
4649 main.log.error( self.name + ": EOF exception found" )
4650 main.log.error( self.name + ": " + self.handle.before )
4651 main.cleanup()
4652 main.exit()
4653 except Exception:
4654 main.log.exception( self.name + ": Uncaught exception!" )
4655 main.cleanup()
4656 main.exit()
4657