blob: d5777f960516ca99e211629b978b55345d88a6ec [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
154 self.handle.expect( "\$" )
155 return main.TRUE
156 else: # some other output
157 main.log.warn( "Unknown repsonse to logout command: '{}'",
158 repr( self.handle.before ) )
159 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700160 elif i == 1: # not in CLI
161 return main.TRUE
162 elif i == 3: # Timeout
163 return main.FALSE
164 else:
andrewonlab9627f432014-11-14 12:45:10 -0500165 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800166 except TypeError:
167 main.log.exception( self.name + ": Object not as expected" )
168 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700171 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 main.cleanup()
173 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700174 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700175 main.log.error( self.name +
176 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800177 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800178 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 main.cleanup()
180 main.exit()
181
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800183 """
andrewonlab95ce8322014-10-13 14:12:04 -0400184 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800185
andrewonlab95ce8322014-10-13 14:12:04 -0400186 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800187 """
andrewonlab95ce8322014-10-13 14:12:04 -0400188 try:
189 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400191 main.cleanup()
192 main.exit()
193 else:
kelvin8ec71442015-01-15 16:57:00 -0800194 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800196 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400197 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800198 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800199 handleBefore = self.handle.before
200 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800201 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800202 self.handle.sendline("")
203 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800204 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400205
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 main.log.info( "Cell call returned: " + handleBefore +
207 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400208
209 return main.TRUE
210
Jon Halld4d4b372015-01-28 16:02:41 -0800211 except TypeError:
212 main.log.exception( self.name + ": Object not as expected" )
213 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400214 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800215 main.log.error( self.name + ": eof exception found" )
216 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400217 main.cleanup()
218 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800220 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400221 main.cleanup()
222 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800223
pingping-lin57a56ce2015-05-20 16:43:48 -0700224 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800225 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800226 """
Jon Hallefbd9792015-03-05 16:11:36 -0800227 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 by user would be used to set the current karaf shell idle timeout.
229 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800230 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 Below is an example to start a session with 60 seconds idle timeout
232 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800233
Hari Krishna25d42f72015-01-05 15:08:28 -0800234 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 Note: karafTimeout is left as str so that this could be read
238 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800239 """
You Wangf69ab392016-01-26 16:34:38 -0800240 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400241 try:
kelvin8ec71442015-01-15 16:57:00 -0800242 self.handle.sendline( "" )
243 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700244 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500245
246 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800247 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500248 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400249
kelvin8ec71442015-01-15 16:57:00 -0800250 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 i = self.handle.expect( [
253 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400255
256 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800258 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800259 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800260 "config:property-set -p org.apache.karaf.shell\
261 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800262 karafTimeout )
263 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400266 return main.TRUE
267 else:
kelvin8ec71442015-01-15 16:57:00 -0800268 # If failed, send ctrl+c to process and try again
269 main.log.info( "Starting CLI failed. Retrying..." )
270 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800272 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
273 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400274 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800276 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800277 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800278 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 "config:property-set -p org.apache.karaf.shell\
280 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800281 karafTimeout )
282 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800284 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400285 return main.TRUE
286 else:
kelvin8ec71442015-01-15 16:57:00 -0800287 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400290
Jon Halld4d4b372015-01-28 16:02:41 -0800291 except TypeError:
292 main.log.exception( self.name + ": Object not as expected" )
293 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800295 main.log.error( self.name + ": EOF exception found" )
296 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400297 main.cleanup()
298 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800300 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400301 main.cleanup()
302 main.exit()
303
suibin zhang116647a2016-05-06 16:30:09 -0700304 def startCellCli( self, karafTimeout="",
305 commandlineTimeout=10, onosStartTimeout=60 ):
306 """
307 Start CLI on onos ecll handle.
308
309 karafTimeout is an optional argument. karafTimeout value passed
310 by user would be used to set the current karaf shell idle timeout.
311 Note that when ever this property is modified the shell will exit and
312 the subsequent login would reflect new idle timeout.
313 Below is an example to start a session with 60 seconds idle timeout
314 ( input value is in milliseconds ):
315
316 tValue = "60000"
317
318 Note: karafTimeout is left as str so that this could be read
319 and passed to startOnosCli from PARAMS file as str.
320 """
321
322 try:
323 self.handle.sendline( "" )
324 x = self.handle.expect( [
325 "\$", "onos>" ], commandlineTimeout)
326
327 if x == 1:
328 main.log.info( "ONOS cli is already running" )
329 return main.TRUE
330
331 # Wait for onos start ( -w ) and enter onos cli
332 self.handle.sendline( "/opt/onos/bin/onos" )
333 i = self.handle.expect( [
334 "onos>",
335 pexpect.TIMEOUT ], onosStartTimeout )
336
337 if i == 0:
338 main.log.info( self.name + " CLI Started successfully" )
339 if karafTimeout:
340 self.handle.sendline(
341 "config:property-set -p org.apache.karaf.shell\
342 sshIdleTimeout " +
343 karafTimeout )
344 self.handle.expect( "\$" )
345 self.handle.sendline( "/opt/onos/bin/onos" )
346 self.handle.expect( "onos>" )
347 return main.TRUE
348 else:
349 # If failed, send ctrl+c to process and try again
350 main.log.info( "Starting CLI failed. Retrying..." )
351 self.handle.send( "\x03" )
352 self.handle.sendline( "/opt/onos/bin/onos" )
353 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
354 timeout=30 )
355 if i == 0:
356 main.log.info( self.name + " CLI Started " +
357 "successfully after retry attempt" )
358 if karafTimeout:
359 self.handle.sendline(
360 "config:property-set -p org.apache.karaf.shell\
361 sshIdleTimeout " +
362 karafTimeout )
363 self.handle.expect( "\$" )
364 self.handle.sendline( "/opt/onos/bin/onos" )
365 self.handle.expect( "onos>" )
366 return main.TRUE
367 else:
368 main.log.error( "Connection to CLI " +
369 self.name + " timeout" )
370 return main.FALSE
371
372 except TypeError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
375 except pexpect.EOF:
376 main.log.error( self.name + ": EOF exception found" )
377 main.log.error( self.name + ": " + self.handle.before )
378 main.cleanup()
379 main.exit()
380 except Exception:
381 main.log.exception( self.name + ": Uncaught exception!" )
382 main.cleanup()
383 main.exit()
384
Jon Hallefbd9792015-03-05 16:11:36 -0800385 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800386 """
387 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800388 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800389 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800390 Available level: DEBUG, TRACE, INFO, WARN, ERROR
391 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800392 """
393 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800394 lvlStr = ""
395 if level:
396 lvlStr = "--level=" + level
397
kelvin-onlab9f541032015-02-04 16:19:53 -0800398 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800399 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700400 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800401 main.log.error( self.name + ": onos cli session closed. ")
402 if self.onosIp:
403 main.log.warn( "Trying to reconnect " + self.onosIp )
404 reconnectResult = self.startOnosCli( self.onosIp )
405 if reconnectResult:
406 main.log.info( self.name + ": onos cli session reconnected." )
407 else:
408 main.log.error( self.name + ": reconnection failed." )
409 main.cleanup()
410 main.exit()
411 else:
412 main.cleanup()
413 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700414 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700415 self.handle.sendline( "" )
416 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800417 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700418 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800420
kelvin-onlab9f541032015-02-04 16:19:53 -0800421 response = self.handle.before
422 if re.search( "Error", response ):
423 return main.FALSE
424 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700425 except pexpect.TIMEOUT:
426 main.log.exception( self.name + ": TIMEOUT exception found" )
427 main.cleanup()
428 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 except pexpect.EOF:
430 main.log.error( self.name + ": EOF exception found" )
431 main.log.error( self.name + ": " + self.handle.before )
432 main.cleanup()
433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800434 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800435 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400436 main.cleanup()
437 main.exit()
438
GlennRCed771242016-01-13 17:02:47 -0800439 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800440 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800441 Send a completely user specified string to
442 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400443 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800444
andrewonlaba18f6bf2014-10-13 19:31:54 -0400445 Warning: There are no sanity checking to commands
446 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800447
kelvin8ec71442015-01-15 16:57:00 -0800448 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400449 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700450 if debug:
451 # NOTE: This adds and average of .4 seconds per call
452 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
453 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800454 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800455 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800456 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800457 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800458 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
459 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700460 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700461 main.log.debug( self.name + ": Raw output" )
462 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700463
464 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800465 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800466 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700467 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700468 main.log.debug( self.name + ": ansiEscape output" )
469 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700470
kelvin-onlabfb521662015-02-27 09:52:40 -0800471 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800472 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700473 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700474 main.log.debug( self.name + ": Removed extra returns " +
475 "from output" )
476 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700477
478 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800479 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700480 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700481 main.log.debug( self.name + ": parsed and stripped output" )
482 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700483
Jon Hall63604932015-02-26 17:09:50 -0800484 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700485 output = response.split( cmdStr.strip(), 1 )
486 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700487 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800490 output = output[1].strip()
491 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800492 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800493 return output
GlennRCed771242016-01-13 17:02:47 -0800494 except pexpect.TIMEOUT:
495 main.log.error( self.name + ":ONOS timeout" )
496 if debug:
497 main.log.debug( self.handle.before )
498 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700499 except IndexError:
500 main.log.exception( self.name + ": Object not as expected" )
501 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800502 except TypeError:
503 main.log.exception( self.name + ": Object not as expected" )
504 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400505 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800506 main.log.error( self.name + ": EOF exception found" )
507 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400508 main.cleanup()
509 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800510 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800511 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400512 main.cleanup()
513 main.exit()
514
kelvin8ec71442015-01-15 16:57:00 -0800515 # IMPORTANT NOTE:
516 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800517 # the cli command changing 'a:b' with 'aB'.
518 # Ex ) onos:topology > onosTopology
519 # onos:links > onosLinks
520 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800521
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800523 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400524 Adds a new cluster node by ID and address information.
525 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800526 * nodeId
527 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400528 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800530 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400531 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 cmdStr = "add-node " + str( nodeId ) + " " +\
533 str( ONOSIp ) + " " + str( tcpPort )
534 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800535 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800536 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800537 main.log.error( "Error in adding node" )
538 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800539 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400540 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400542 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800543 except AssertionError:
544 main.log.exception( "" )
545 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800546 except TypeError:
547 main.log.exception( self.name + ": Object not as expected" )
548 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800550 main.log.error( self.name + ": EOF exception found" )
551 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400552 main.cleanup()
553 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800554 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800555 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400556 main.cleanup()
557 main.exit()
558
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800560 """
andrewonlab86dc3082014-10-13 18:18:38 -0400561 Removes a cluster by ID
562 Issues command: 'remove-node [<node-id>]'
563 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800565 """
andrewonlab86dc3082014-10-13 18:18:38 -0400566 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400567
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700569 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800570 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700571 if re.search( "Error", handle ):
572 main.log.error( "Error in removing node" )
573 main.log.error( handle )
574 return main.FALSE
575 else:
576 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800577 except AssertionError:
578 main.log.exception( "" )
579 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800580 except TypeError:
581 main.log.exception( self.name + ": Object not as expected" )
582 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400583 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800584 main.log.error( self.name + ": EOF exception found" )
585 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400586 main.cleanup()
587 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800588 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800589 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400590 main.cleanup()
591 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592
Jon Hall61282e32015-03-19 11:34:11 -0700593 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800594 """
andrewonlab7c211572014-10-15 16:45:20 -0400595 List the nodes currently visible
596 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700597 Optional argument:
598 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800599 """
andrewonlab7c211572014-10-15 16:45:20 -0400600 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700601 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700602 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700603 cmdStr += " -j"
604 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800605 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700606 return output
Jon Hallc6793552016-01-19 14:18:37 -0800607 except AssertionError:
608 main.log.exception( "" )
609 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800610 except TypeError:
611 main.log.exception( self.name + ": Object not as expected" )
612 return None
andrewonlab7c211572014-10-15 16:45:20 -0400613 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800614 main.log.error( self.name + ": EOF exception found" )
615 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400616 main.cleanup()
617 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800618 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800619 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400620 main.cleanup()
621 main.exit()
622
kelvin8ec71442015-01-15 16:57:00 -0800623 def topology( self ):
624 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700625 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700626 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700627 Return:
628 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800629 """
andrewonlab95ce8322014-10-13 14:12:04 -0400630 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700631 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800633 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400635 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800636 except AssertionError:
637 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800638 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400645 main.cleanup()
646 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400649 main.cleanup()
650 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800651
jenkins7ead5a82015-03-13 10:28:21 -0700652 def deviceRemove( self, deviceId ):
653 """
654 Removes particular device from storage
655
656 TODO: refactor this function
657 """
658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "device-remove " + str( deviceId )
660 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800661 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 if re.search( "Error", handle ):
663 main.log.error( "Error in removing device" )
664 main.log.error( handle )
665 return main.FALSE
666 else:
667 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
670 return None
jenkins7ead5a82015-03-13 10:28:21 -0700671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
674 except pexpect.EOF:
675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
677 main.cleanup()
678 main.exit()
679 except Exception:
680 main.log.exception( self.name + ": Uncaught exception!" )
681 main.cleanup()
682 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700683
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800685 """
Jon Hall7b02d952014-10-17 20:14:54 -0400686 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400687 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800689 """
andrewonlab86dc3082014-10-13 18:18:38 -0400690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700693 cmdStr += " -j"
694 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800695 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700696 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800697 except AssertionError:
698 main.log.exception( "" )
699 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800700 except TypeError:
701 main.log.exception( self.name + ": Object not as expected" )
702 return None
andrewonlab7c211572014-10-15 16:45:20 -0400703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800704 main.log.error( self.name + ": EOF exception found" )
705 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400706 main.cleanup()
707 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800708 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800709 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400710 main.cleanup()
711 main.exit()
712
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800714 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800715 This balances the devices across all controllers
716 by issuing command: 'onos> onos:balance-masters'
717 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800718 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800719 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700721 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800722 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 if re.search( "Error", handle ):
724 main.log.error( "Error in balancing masters" )
725 main.log.error( handle )
726 return main.FALSE
727 else:
728 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800729 except AssertionError:
730 main.log.exception( "" )
731 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800732 except TypeError:
733 main.log.exception( self.name + ": Object not as expected" )
734 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800735 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800736 main.log.error( self.name + ": EOF exception found" )
737 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800738 main.cleanup()
739 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800742 main.cleanup()
743 main.exit()
744
Jon Hallc6793552016-01-19 14:18:37 -0800745 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700746 """
747 Returns the output of the masters command.
748 Optional argument:
749 * jsonFormat - boolean indicating if you want output in json
750 """
751 try:
752 cmdStr = "onos:masters"
753 if jsonFormat:
754 cmdStr += " -j"
755 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800756 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700757 return output
Jon Hallc6793552016-01-19 14:18:37 -0800758 except AssertionError:
759 main.log.exception( "" )
760 return None
acsmars24950022015-07-30 18:00:43 -0700761 except TypeError:
762 main.log.exception( self.name + ": Object not as expected" )
763 return None
764 except pexpect.EOF:
765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
767 main.cleanup()
768 main.exit()
769 except Exception:
770 main.log.exception( self.name + ": Uncaught exception!" )
771 main.cleanup()
772 main.exit()
773
Jon Hallc6793552016-01-19 14:18:37 -0800774 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700775 """
776 Uses the master command to check that the devices' leadership
777 is evenly divided
778
779 Dependencies: checkMasters() and summary()
780
781 Returns main.True if the devices are balanced
782 Returns main.False if the devices are unbalanced
783 Exits on Exception
784 Returns None on TypeError
785 """
786 try:
Jon Hallc6793552016-01-19 14:18:37 -0800787 summaryOutput = self.summary()
788 totalDevices = json.loads( summaryOutput )[ "devices" ]
789 except ( TypeError, ValueError ):
790 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
791 return None
792 try:
acsmars24950022015-07-30 18:00:43 -0700793 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800794 mastersOutput = self.checkMasters()
795 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700796 first = masters[ 0 ][ "size" ]
797 for master in masters:
798 totalOwnedDevices += master[ "size" ]
799 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
800 main.log.error( "Mastership not balanced" )
801 main.log.info( "\n" + self.checkMasters( False ) )
802 return main.FALSE
803 main.log.info( "Mastership balanced between " \
804 + str( len(masters) ) + " masters" )
805 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800806 except ( TypeError, ValueError ):
807 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700808 return None
809 except pexpect.EOF:
810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
812 main.cleanup()
813 main.exit()
814 except Exception:
815 main.log.exception( self.name + ": Uncaught exception!" )
816 main.cleanup()
817 main.exit()
818
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800820 """
Jon Halle8217482014-10-17 13:49:14 -0400821 Lists all core links
822 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800824 """
Jon Halle8217482014-10-17 13:49:14 -0400825 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700826 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700828 cmdStr += " -j"
829 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800830 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700831 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800832 except AssertionError:
833 main.log.exception( "" )
834 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800835 except TypeError:
836 main.log.exception( self.name + ": Object not as expected" )
837 return None
Jon Halle8217482014-10-17 13:49:14 -0400838 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800839 main.log.error( self.name + ": EOF exception found" )
840 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400841 main.cleanup()
842 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800843 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800844 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400845 main.cleanup()
846 main.exit()
847
kelvin-onlabd3b64892015-01-20 13:26:24 -0800848 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Halle8217482014-10-17 13:49:14 -0400850 Lists all ports
851 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800853 """
Jon Halle8217482014-10-17 13:49:14 -0400854 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700855 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700857 cmdStr += " -j"
858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800859 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700860 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800861 except AssertionError:
862 main.log.exception( "" )
863 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800864 except TypeError:
865 main.log.exception( self.name + ": Object not as expected" )
866 return None
Jon Halle8217482014-10-17 13:49:14 -0400867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400870 main.cleanup()
871 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800872 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800873 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400874 main.cleanup()
875 main.exit()
876
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800878 """
Jon Hall983a1702014-10-28 18:44:22 -0400879 Lists all devices and the controllers with roles assigned to them
880 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800882 """
andrewonlab7c211572014-10-15 16:45:20 -0400883 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 cmdStr += " -j"
887 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800888 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700889 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800890 except AssertionError:
891 main.log.exception( "" )
892 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800893 except TypeError:
894 main.log.exception( self.name + ": Object not as expected" )
895 return None
Jon Hall983a1702014-10-28 18:44:22 -0400896 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400899 main.cleanup()
900 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800901 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800902 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400903 main.cleanup()
904 main.exit()
905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800907 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800908 Given the a string containing the json representation of the "roles"
909 cli command and a partial or whole device id, returns a json object
910 containing the roles output for the first device whose id contains
911 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400912
913 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800914 A dict of the role assignments for the given device or
915 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800916 """
Jon Hall983a1702014-10-28 18:44:22 -0400917 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400919 return None
920 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 rawRoles = self.roles()
922 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800923 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800925 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400927 return device
928 return None
Jon Hallc6793552016-01-19 14:18:37 -0800929 except ( TypeError, ValueError ):
930 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800931 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400932 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800933 main.log.error( self.name + ": EOF exception found" )
934 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400935 main.cleanup()
936 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800937 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800938 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400939 main.cleanup()
940 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800941
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800943 """
Jon Hall94fd0472014-12-08 11:52:42 -0800944 Iterates through each device and checks if there is a master assigned
945 Returns: main.TRUE if each device has a master
946 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800947 """
Jon Hall94fd0472014-12-08 11:52:42 -0800948 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 rawRoles = self.roles()
950 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800951 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800953 # print device
954 if device[ 'master' ] == "none":
955 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800956 return main.FALSE
957 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800958 except ( TypeError, ValueError ):
959 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800960 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800962 main.log.error( self.name + ": EOF exception found" )
963 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800964 main.cleanup()
965 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800966 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800967 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800968 main.cleanup()
969 main.exit()
970
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800972 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400973 Returns string of paths, and the cost.
974 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800975 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400976 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
978 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800979 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800980 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800981 main.log.error( "Error in getting paths" )
982 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400983 else:
kelvin8ec71442015-01-15 16:57:00 -0800984 path = handle.split( ";" )[ 0 ]
985 cost = handle.split( ";" )[ 1 ]
986 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800987 except AssertionError:
988 main.log.exception( "" )
989 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800990 except TypeError:
991 main.log.exception( self.name + ": Object not as expected" )
992 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400993 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800994 main.log.error( self.name + ": EOF exception found" )
995 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400996 main.cleanup()
997 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800998 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800999 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001000 main.cleanup()
1001 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001002
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001004 """
Jon Hallffb386d2014-11-21 13:43:38 -08001005 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001006 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001008 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001009 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001010 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001012 cmdStr += " -j"
1013 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001014 if handle:
1015 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001016 # TODO: Maybe make this less hardcoded
1017 # ConsistentMap Exceptions
1018 assert "org.onosproject.store.service" not in handle
1019 # Node not leader
1020 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001021 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001022 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001023 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001024 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001026 except TypeError:
1027 main.log.exception( self.name + ": Object not as expected" )
1028 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.error( self.name + ": EOF exception found" )
1031 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 main.cleanup()
1033 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001034 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001035 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001036 main.cleanup()
1037 main.exit()
1038
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001040 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001041 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001042
Jon Hallefbd9792015-03-05 16:11:36 -08001043 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001044 partial mac address
1045
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001047 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 try:
kelvin8ec71442015-01-15 16:57:00 -08001049 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 return None
1051 else:
1052 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 rawHosts = self.hosts()
1054 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001055 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001056 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001057 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001058 if not host:
1059 pass
1060 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001061 return host
1062 return None
Jon Hallc6793552016-01-19 14:18:37 -08001063 except ( TypeError, ValueError ):
1064 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001065 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001067 main.log.error( self.name + ": EOF exception found" )
1068 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 main.cleanup()
1070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001072 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001073 main.cleanup()
1074 main.exit()
1075
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001077 """
1078 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001079 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001080
andrewonlab3f0a4af2014-10-17 12:25:14 -04001081 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001083 IMPORTANT:
1084 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001085 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001086 Furthermore, it assumes that value of VLAN is '-1'
1087 Description:
kelvin8ec71442015-01-15 16:57:00 -08001088 Converts mininet hosts ( h1, h2, h3... ) into
1089 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1090 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001091 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001093
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001095 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 hostHex = hex( int( host ) ).zfill( 12 )
1097 hostHex = str( hostHex ).replace( 'x', '0' )
1098 i = iter( str( hostHex ) )
1099 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1100 hostHex = hostHex + "/-1"
1101 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001102
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001104
Jon Halld4d4b372015-01-28 16:02:41 -08001105 except TypeError:
1106 main.log.exception( self.name + ": Object not as expected" )
1107 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001108 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001109 main.log.error( self.name + ": EOF exception found" )
1110 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001111 main.cleanup()
1112 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001114 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001115 main.cleanup()
1116 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001117
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001119 """
andrewonlabe6745342014-10-17 14:29:13 -04001120 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 * hostIdOne: ONOS host id for host1
1122 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001123 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001124 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001125 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001126 Returns:
1127 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001128 """
andrewonlabe6745342014-10-17 14:29:13 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1131 " " + str( hostIdTwo )
1132 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001133 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001134 if re.search( "Error", handle ):
1135 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001136 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001137 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001138 else:
1139 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001140 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1141 match = re.search('id=0x([\da-f]+),', handle)
1142 if match:
1143 return match.group()[3:-1]
1144 else:
1145 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001146 main.log.debug( "Response from ONOS was: " +
1147 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001148 return None
Jon Hallc6793552016-01-19 14:18:37 -08001149 except AssertionError:
1150 main.log.exception( "" )
1151 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001152 except TypeError:
1153 main.log.exception( self.name + ": Object not as expected" )
1154 return None
andrewonlabe6745342014-10-17 14:29:13 -04001155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001156 main.log.error( self.name + ": EOF exception found" )
1157 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001158 main.cleanup()
1159 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001160 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001161 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001162 main.cleanup()
1163 main.exit()
1164
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001166 """
andrewonlab7b31d232014-10-24 13:31:47 -04001167 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 * ingressDevice: device id of ingress device
1169 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001170 Optional:
1171 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001172 Description:
1173 Adds an optical intent by specifying an ingress and egress device
1174 Returns:
1175 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001176 """
andrewonlab7b31d232014-10-24 13:31:47 -04001177 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1179 " " + str( egressDevice )
1180 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001181 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001182 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001183 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001184 main.log.error( "Error in adding Optical intent" )
1185 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001186 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 main.log.info( "Optical intent installed between " +
1188 str( ingressDevice ) + " and " +
1189 str( egressDevice ) )
1190 match = re.search('id=0x([\da-f]+),', handle)
1191 if match:
1192 return match.group()[3:-1]
1193 else:
1194 main.log.error( "Error, intent ID not found" )
1195 return None
Jon Hallc6793552016-01-19 14:18:37 -08001196 except AssertionError:
1197 main.log.exception( "" )
1198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001199 except TypeError:
1200 main.log.exception( self.name + ": Object not as expected" )
1201 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( self.name + ": EOF exception found" )
1204 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001205 main.cleanup()
1206 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001209 main.cleanup()
1210 main.exit()
1211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001213 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 ingressDevice,
1215 egressDevice,
1216 portIngress="",
1217 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001218 ethType="",
1219 ethSrc="",
1220 ethDst="",
1221 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 ipProto="",
1224 ipSrc="",
1225 ipDst="",
1226 tcpSrc="",
1227 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001228 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001229 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 * ingressDevice: device id of ingress device
1231 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001232 Optional:
1233 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001234 * ethSrc: specify ethSrc ( i.e. src mac addr )
1235 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001236 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001237 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001238 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001239 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001240 * ipSrc: specify ip source address
1241 * ipDst: specify ip destination address
1242 * tcpSrc: specify tcp source port
1243 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001244 Description:
kelvin8ec71442015-01-15 16:57:00 -08001245 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001246 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001247 Returns:
1248 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001249
Jon Halle3f39ff2015-01-13 11:50:53 -08001250 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001251 options developers provide for point-to-point
1252 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001253 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001254 try:
kelvin8ec71442015-01-15 16:57:00 -08001255 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001256 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001258 and not ipProto and not ipSrc and not ipDst \
1259 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001260 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001261
andrewonlab289e4b72014-10-21 21:24:18 -04001262 else:
andrewonlab36af3822014-11-18 17:48:18 -05001263 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001264
andrewonlab0c0a6772014-10-22 12:31:18 -04001265 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001266 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001267 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001268 cmd += " --ethSrc " + str( ethSrc )
1269 if ethDst:
1270 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001271 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001272 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001274 cmd += " --lambda "
1275 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001276 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001277 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001278 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001279 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001280 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001281 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001282 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001283 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001284 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001285
kelvin8ec71442015-01-15 16:57:00 -08001286 # Check whether the user appended the port
1287 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001288 if "/" in ingressDevice:
1289 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001290 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001292 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001293 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001294 # Would it make sense to throw an exception and exit
1295 # the test?
1296 return None
andrewonlab36af3822014-11-18 17:48:18 -05001297
kelvin8ec71442015-01-15 16:57:00 -08001298 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 str( ingressDevice ) + "/" +\
1300 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001301
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 if "/" in egressDevice:
1303 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001304 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001306 main.log.error( "You must specify the egress port" )
1307 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001308
kelvin8ec71442015-01-15 16:57:00 -08001309 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 str( egressDevice ) + "/" +\
1311 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001312
kelvin-onlab898a6c62015-01-16 14:13:53 -08001313 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001314 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001315 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001316 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001317 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001318 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001319 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001320 # TODO: print out all the options in this message?
1321 main.log.info( "Point-to-point intent installed between " +
1322 str( ingressDevice ) + " and " +
1323 str( egressDevice ) )
1324 match = re.search('id=0x([\da-f]+),', handle)
1325 if match:
1326 return match.group()[3:-1]
1327 else:
1328 main.log.error( "Error, intent ID not found" )
1329 return None
Jon Hallc6793552016-01-19 14:18:37 -08001330 except AssertionError:
1331 main.log.exception( "" )
1332 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001333 except TypeError:
1334 main.log.exception( self.name + ": Object not as expected" )
1335 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001336 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001337 main.log.error( self.name + ": EOF exception found" )
1338 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001339 main.cleanup()
1340 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001341 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001342 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001343 main.cleanup()
1344 main.exit()
1345
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001347 self,
shahshreyac2f97072015-03-19 17:04:29 -07001348 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001350 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001352 ethType="",
1353 ethSrc="",
1354 ethDst="",
1355 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001356 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001357 ipProto="",
1358 ipSrc="",
1359 ipDst="",
1360 tcpSrc="",
1361 tcpDst="",
1362 setEthSrc="",
1363 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001364 """
shahshreyad0c80432014-12-04 16:56:05 -08001365 Note:
shahshreya70622b12015-03-19 17:19:00 -07001366 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001367 is same. That is, all ingress devices include port numbers
1368 with a "/" or all ingress devices could specify device
1369 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001370 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001371 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001372 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001374 Optional:
1375 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001376 * ethSrc: specify ethSrc ( i.e. src mac addr )
1377 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001378 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001380 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001381 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001382 * ipSrc: specify ip source address
1383 * ipDst: specify ip destination address
1384 * tcpSrc: specify tcp source port
1385 * tcpDst: specify tcp destination port
1386 * setEthSrc: action to Rewrite Source MAC Address
1387 * setEthDst: action to Rewrite Destination MAC Address
1388 Description:
kelvin8ec71442015-01-15 16:57:00 -08001389 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001390 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001391 Returns:
1392 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001393
Jon Halle3f39ff2015-01-13 11:50:53 -08001394 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001395 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001396 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001397 """
shahshreyad0c80432014-12-04 16:56:05 -08001398 try:
kelvin8ec71442015-01-15 16:57:00 -08001399 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001400 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001402 and not ipProto and not ipSrc and not ipDst\
1403 and not tcpSrc and not tcpDst and not setEthSrc\
1404 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001405 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001406
1407 else:
1408 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001409
shahshreyad0c80432014-12-04 16:56:05 -08001410 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001411 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001412 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001413 cmd += " --ethSrc " + str( ethSrc )
1414 if ethDst:
1415 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001416 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001417 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001419 cmd += " --lambda "
1420 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001421 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001422 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001423 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001424 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001425 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001426 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001427 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001428 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001429 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001430 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001431 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001432 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001433 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001434
kelvin8ec71442015-01-15 16:57:00 -08001435 # Check whether the user appended the port
1436 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001437
1438 if portIngressList is None:
1439 for ingressDevice in ingressDeviceList:
1440 if "/" in ingressDevice:
1441 cmd += " " + str( ingressDevice )
1442 else:
1443 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001444 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001445 # TODO: perhaps more meaningful return
1446 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001447 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001448 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001449 for ingressDevice, portIngress in zip( ingressDeviceList,
1450 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001451 cmd += " " + \
1452 str( ingressDevice ) + "/" +\
1453 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001454 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001455 main.log.error( "Device list and port list does not " +
1456 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001457 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 if "/" in egressDevice:
1459 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001460 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001462 main.log.error( "You must specify " +
1463 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001464 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001465
kelvin8ec71442015-01-15 16:57:00 -08001466 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001467 str( egressDevice ) + "/" +\
1468 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001469 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001470 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001471 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001473 main.log.error( "Error in adding multipoint-to-singlepoint " +
1474 "intent" )
1475 return None
shahshreyad0c80432014-12-04 16:56:05 -08001476 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001477 match = re.search('id=0x([\da-f]+),', handle)
1478 if match:
1479 return match.group()[3:-1]
1480 else:
1481 main.log.error( "Error, intent ID not found" )
1482 return None
Jon Hallc6793552016-01-19 14:18:37 -08001483 except AssertionError:
1484 main.log.exception( "" )
1485 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001486 except TypeError:
1487 main.log.exception( self.name + ": Object not as expected" )
1488 return None
1489 except pexpect.EOF:
1490 main.log.error( self.name + ": EOF exception found" )
1491 main.log.error( self.name + ": " + self.handle.before )
1492 main.cleanup()
1493 main.exit()
1494 except Exception:
1495 main.log.exception( self.name + ": Uncaught exception!" )
1496 main.cleanup()
1497 main.exit()
1498
1499 def addSinglepointToMultipointIntent(
1500 self,
1501 ingressDevice,
1502 egressDeviceList,
1503 portIngress="",
1504 portEgressList=None,
1505 ethType="",
1506 ethSrc="",
1507 ethDst="",
1508 bandwidth="",
1509 lambdaAlloc=False,
1510 ipProto="",
1511 ipSrc="",
1512 ipDst="",
1513 tcpSrc="",
1514 tcpDst="",
1515 setEthSrc="",
1516 setEthDst="" ):
1517 """
1518 Note:
1519 This function assumes the format of all egress devices
1520 is same. That is, all egress devices include port numbers
1521 with a "/" or all egress devices could specify device
1522 ids and port numbers seperately.
1523 Required:
1524 * EgressDeviceList: List of device ids of egress device
1525 ( Atleast 2 eress devices required in the list )
1526 * ingressDevice: device id of ingress device
1527 Optional:
1528 * ethType: specify ethType
1529 * ethSrc: specify ethSrc ( i.e. src mac addr )
1530 * ethDst: specify ethDst ( i.e. dst mac addr )
1531 * bandwidth: specify bandwidth capacity of link
1532 * lambdaAlloc: if True, intent will allocate lambda
1533 for the specified intent
1534 * ipProto: specify ip protocol
1535 * ipSrc: specify ip source address
1536 * ipDst: specify ip destination address
1537 * tcpSrc: specify tcp source port
1538 * tcpDst: specify tcp destination port
1539 * setEthSrc: action to Rewrite Source MAC Address
1540 * setEthDst: action to Rewrite Destination MAC Address
1541 Description:
1542 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1543 specifying device id's and optional fields
1544 Returns:
1545 A string of the intent id or None on error
1546
1547 NOTE: This function may change depending on the
1548 options developers provide for singlepoint-to-multipoint
1549 intent via cli
1550 """
1551 try:
1552 # If there are no optional arguments
1553 if not ethType and not ethSrc and not ethDst\
1554 and not bandwidth and not lambdaAlloc\
1555 and not ipProto and not ipSrc and not ipDst\
1556 and not tcpSrc and not tcpDst and not setEthSrc\
1557 and not setEthDst:
1558 cmd = "add-single-to-multi-intent"
1559
1560 else:
1561 cmd = "add-single-to-multi-intent"
1562
1563 if ethType:
1564 cmd += " --ethType " + str( ethType )
1565 if ethSrc:
1566 cmd += " --ethSrc " + str( ethSrc )
1567 if ethDst:
1568 cmd += " --ethDst " + str( ethDst )
1569 if bandwidth:
1570 cmd += " --bandwidth " + str( bandwidth )
1571 if lambdaAlloc:
1572 cmd += " --lambda "
1573 if ipProto:
1574 cmd += " --ipProto " + str( ipProto )
1575 if ipSrc:
1576 cmd += " --ipSrc " + str( ipSrc )
1577 if ipDst:
1578 cmd += " --ipDst " + str( ipDst )
1579 if tcpSrc:
1580 cmd += " --tcpSrc " + str( tcpSrc )
1581 if tcpDst:
1582 cmd += " --tcpDst " + str( tcpDst )
1583 if setEthSrc:
1584 cmd += " --setEthSrc " + str( setEthSrc )
1585 if setEthDst:
1586 cmd += " --setEthDst " + str( setEthDst )
1587
1588 # Check whether the user appended the port
1589 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001590
kelvin-onlabb9408212015-04-01 13:34:04 -07001591 if "/" in ingressDevice:
1592 cmd += " " + str( ingressDevice )
1593 else:
1594 if not portIngress:
1595 main.log.error( "You must specify " +
1596 "the Ingress port" )
1597 return main.FALSE
1598
1599 cmd += " " +\
1600 str( ingressDevice ) + "/" +\
1601 str( portIngress )
1602
1603 if portEgressList is None:
1604 for egressDevice in egressDeviceList:
1605 if "/" in egressDevice:
1606 cmd += " " + str( egressDevice )
1607 else:
1608 main.log.error( "You must specify " +
1609 "the egress port" )
1610 # TODO: perhaps more meaningful return
1611 return main.FALSE
1612 else:
1613 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001614 for egressDevice, portEgress in zip( egressDeviceList,
1615 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001616 cmd += " " + \
1617 str( egressDevice ) + "/" +\
1618 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001619 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001620 main.log.error( "Device list and port list does not " +
1621 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001622 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001623 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001624 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001625 # If error, return error message
1626 if re.search( "Error", handle ):
1627 main.log.error( "Error in adding singlepoint-to-multipoint " +
1628 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001629 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001630 else:
1631 match = re.search('id=0x([\da-f]+),', handle)
1632 if match:
1633 return match.group()[3:-1]
1634 else:
1635 main.log.error( "Error, intent ID not found" )
1636 return None
Jon Hallc6793552016-01-19 14:18:37 -08001637 except AssertionError:
1638 main.log.exception( "" )
1639 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001640 except TypeError:
1641 main.log.exception( self.name + ": Object not as expected" )
1642 return None
shahshreyad0c80432014-12-04 16:56:05 -08001643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001644 main.log.error( self.name + ": EOF exception found" )
1645 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001646 main.cleanup()
1647 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001648 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001649 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001650 main.cleanup()
1651 main.exit()
1652
Hari Krishna9e232602015-04-13 17:29:08 -07001653 def addMplsIntent(
1654 self,
1655 ingressDevice,
1656 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001657 ingressPort="",
1658 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001659 ethType="",
1660 ethSrc="",
1661 ethDst="",
1662 bandwidth="",
1663 lambdaAlloc=False,
1664 ipProto="",
1665 ipSrc="",
1666 ipDst="",
1667 tcpSrc="",
1668 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001669 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001670 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001671 priority=""):
1672 """
1673 Required:
1674 * ingressDevice: device id of ingress device
1675 * egressDevice: device id of egress device
1676 Optional:
1677 * ethType: specify ethType
1678 * ethSrc: specify ethSrc ( i.e. src mac addr )
1679 * ethDst: specify ethDst ( i.e. dst mac addr )
1680 * bandwidth: specify bandwidth capacity of link
1681 * lambdaAlloc: if True, intent will allocate lambda
1682 for the specified intent
1683 * ipProto: specify ip protocol
1684 * ipSrc: specify ip source address
1685 * ipDst: specify ip destination address
1686 * tcpSrc: specify tcp source port
1687 * tcpDst: specify tcp destination port
1688 * ingressLabel: Ingress MPLS label
1689 * egressLabel: Egress MPLS label
1690 Description:
1691 Adds MPLS intent by
1692 specifying device id's and optional fields
1693 Returns:
1694 A string of the intent id or None on error
1695
1696 NOTE: This function may change depending on the
1697 options developers provide for MPLS
1698 intent via cli
1699 """
1700 try:
1701 # If there are no optional arguments
1702 if not ethType and not ethSrc and not ethDst\
1703 and not bandwidth and not lambdaAlloc \
1704 and not ipProto and not ipSrc and not ipDst \
1705 and not tcpSrc and not tcpDst and not ingressLabel \
1706 and not egressLabel:
1707 cmd = "add-mpls-intent"
1708
1709 else:
1710 cmd = "add-mpls-intent"
1711
1712 if ethType:
1713 cmd += " --ethType " + str( ethType )
1714 if ethSrc:
1715 cmd += " --ethSrc " + str( ethSrc )
1716 if ethDst:
1717 cmd += " --ethDst " + str( ethDst )
1718 if bandwidth:
1719 cmd += " --bandwidth " + str( bandwidth )
1720 if lambdaAlloc:
1721 cmd += " --lambda "
1722 if ipProto:
1723 cmd += " --ipProto " + str( ipProto )
1724 if ipSrc:
1725 cmd += " --ipSrc " + str( ipSrc )
1726 if ipDst:
1727 cmd += " --ipDst " + str( ipDst )
1728 if tcpSrc:
1729 cmd += " --tcpSrc " + str( tcpSrc )
1730 if tcpDst:
1731 cmd += " --tcpDst " + str( tcpDst )
1732 if ingressLabel:
1733 cmd += " --ingressLabel " + str( ingressLabel )
1734 if egressLabel:
1735 cmd += " --egressLabel " + str( egressLabel )
1736 if priority:
1737 cmd += " --priority " + str( priority )
1738
1739 # Check whether the user appended the port
1740 # or provided it as an input
1741 if "/" in ingressDevice:
1742 cmd += " " + str( ingressDevice )
1743 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001744 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001745 main.log.error( "You must specify the ingress port" )
1746 return None
1747
1748 cmd += " " + \
1749 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001750 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001751
1752 if "/" in egressDevice:
1753 cmd += " " + str( egressDevice )
1754 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001755 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001756 main.log.error( "You must specify the egress port" )
1757 return None
1758
1759 cmd += " " +\
1760 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001761 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001762
1763 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001764 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001765 # If error, return error message
1766 if re.search( "Error", handle ):
1767 main.log.error( "Error in adding mpls intent" )
1768 return None
1769 else:
1770 # TODO: print out all the options in this message?
1771 main.log.info( "MPLS intent installed between " +
1772 str( ingressDevice ) + " and " +
1773 str( egressDevice ) )
1774 match = re.search('id=0x([\da-f]+),', handle)
1775 if match:
1776 return match.group()[3:-1]
1777 else:
1778 main.log.error( "Error, intent ID not found" )
1779 return None
Jon Hallc6793552016-01-19 14:18:37 -08001780 except AssertionError:
1781 main.log.exception( "" )
1782 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001783 except TypeError:
1784 main.log.exception( self.name + ": Object not as expected" )
1785 return None
1786 except pexpect.EOF:
1787 main.log.error( self.name + ": EOF exception found" )
1788 main.log.error( self.name + ": " + self.handle.before )
1789 main.cleanup()
1790 main.exit()
1791 except Exception:
1792 main.log.exception( self.name + ": Uncaught exception!" )
1793 main.cleanup()
1794 main.exit()
1795
Jon Hallefbd9792015-03-05 16:11:36 -08001796 def removeIntent( self, intentId, app='org.onosproject.cli',
1797 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001798 """
shahshreya1c818fc2015-02-26 13:44:08 -08001799 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001800 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001801 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001802 -p or --purge: Purge the intent from the store after removal
1803
Jon Halle3f39ff2015-01-13 11:50:53 -08001804 Returns:
1805 main.False on error and
1806 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001807 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001808 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001809 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001810 if purge:
1811 cmdStr += " -p"
1812 if sync:
1813 cmdStr += " -s"
1814
1815 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001817 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001818 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001819 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001820 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001821 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001822 # TODO: Should this be main.TRUE
1823 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001824 except AssertionError:
1825 main.log.exception( "" )
1826 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001827 except TypeError:
1828 main.log.exception( self.name + ": Object not as expected" )
1829 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001830 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001831 main.log.error( self.name + ": EOF exception found" )
1832 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001833 main.cleanup()
1834 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001835 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001836 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001837 main.cleanup()
1838 main.exit()
1839
Jeremy42df2e72016-02-23 16:37:46 -08001840 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1841 """
1842 Description:
1843 Remove all the intents
1844 Optional args:-
1845 -s or --sync: Waits for the removal before returning
1846 -p or --purge: Purge the intent from the store after removal
1847 Returns:
1848 Returns main.TRUE if all intents are removed, otherwise returns
1849 main.FALSE; Returns None for exception
1850 """
1851 try:
1852 cmdStr = "remove-intent"
1853 if purge:
1854 cmdStr += " -p"
1855 if sync:
1856 cmdStr += " -s"
1857
1858 cmdStr += " " + app
1859 handle = self.sendline( cmdStr )
1860 assert "Command not found:" not in handle, handle
1861 if re.search( "Error", handle ):
1862 main.log.error( "Error in removing intent" )
1863 return main.FALSE
1864 else:
1865 return main.TRUE
1866 except AssertionError:
1867 main.log.exception( "" )
1868 return None
1869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
1872 except pexpect.EOF:
1873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
1875 main.cleanup()
1876 main.exit()
1877 except Exception:
1878 main.log.exception( self.name + ": Uncaught exception!" )
1879 main.cleanup()
1880 main.exit()
1881
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001882 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001883 """
1884 Purges all WITHDRAWN Intents
1885 """
1886 try:
1887 cmdStr = "purge-intents"
1888 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001889 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001890 if re.search( "Error", handle ):
1891 main.log.error( "Error in purging intents" )
1892 return main.FALSE
1893 else:
1894 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001895 except AssertionError:
1896 main.log.exception( "" )
1897 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001898 except TypeError:
1899 main.log.exception( self.name + ": Object not as expected" )
1900 return None
1901 except pexpect.EOF:
1902 main.log.error( self.name + ": EOF exception found" )
1903 main.log.error( self.name + ": " + self.handle.before )
1904 main.cleanup()
1905 main.exit()
1906 except Exception:
1907 main.log.exception( self.name + ": Uncaught exception!" )
1908 main.cleanup()
1909 main.exit()
1910
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001912 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001913 NOTE: This method should be used after installing application:
1914 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001915 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001916 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001917 Description:
1918 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001919 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001920 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001921 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001923 cmdStr += " -j"
1924 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001925 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001927 except AssertionError:
1928 main.log.exception( "" )
1929 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001930 except TypeError:
1931 main.log.exception( self.name + ": Object not as expected" )
1932 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001933 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001934 main.log.error( self.name + ": EOF exception found" )
1935 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001936 main.cleanup()
1937 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001938 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001939 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001940 main.cleanup()
1941 main.exit()
1942
pingping-lin54b03372015-08-13 14:43:10 -07001943 def ipv4RouteNumber( self ):
1944 """
1945 NOTE: This method should be used after installing application:
1946 onos-app-sdnip
1947 Description:
1948 Obtain the total IPv4 routes number in the system
1949 """
1950 try:
1951 cmdStr = "routes -s -j"
1952 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001953 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001954 jsonResult = json.loads( handle )
1955 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001956 except AssertionError:
1957 main.log.exception( "" )
1958 return None
1959 except ( TypeError, ValueError ):
1960 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001961 return None
1962 except pexpect.EOF:
1963 main.log.error( self.name + ": EOF exception found" )
1964 main.log.error( self.name + ": " + self.handle.before )
1965 main.cleanup()
1966 main.exit()
1967 except Exception:
1968 main.log.exception( self.name + ": Uncaught exception!" )
1969 main.cleanup()
1970 main.exit()
1971
pingping-lin8244a3b2015-09-16 13:36:56 -07001972 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001973 """
andrewonlabe6745342014-10-17 14:29:13 -04001974 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001975 Obtain intents from the ONOS cli.
1976 Optional:
1977 * jsonFormat: Enable output formatting in json, default to True
1978 * summary: Whether only output the intent summary, defaults to False
1979 * type: Only output a certain type of intent. This options is valid
1980 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001981 """
andrewonlabe6745342014-10-17 14:29:13 -04001982 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001983 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001984 if summary:
1985 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001986 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001987 cmdStr += " -j"
1988 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001989 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001990 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001991 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001992 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001993 else:
Jon Hallff566d52016-01-15 14:45:36 -08001994 intentType = ""
1995 # IF we want the summary of a specific intent type
1996 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001997 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001998 if intentType in jsonResult.keys():
1999 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002000 else:
Jon Hallff566d52016-01-15 14:45:36 -08002001 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002002 return handle
2003 else:
2004 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002005 except AssertionError:
2006 main.log.exception( "" )
2007 return None
2008 except ( TypeError, ValueError ):
2009 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002010 return None
2011 except pexpect.EOF:
2012 main.log.error( self.name + ": EOF exception found" )
2013 main.log.error( self.name + ": " + self.handle.before )
2014 main.cleanup()
2015 main.exit()
2016 except Exception:
2017 main.log.exception( self.name + ": Uncaught exception!" )
2018 main.cleanup()
2019 main.exit()
2020
kelvin-onlab54400a92015-02-26 18:05:51 -08002021 def getIntentState(self, intentsId, intentsJson=None):
2022 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002023 Check intent state.
2024 Accepts a single intent ID (string type) or a list of intent IDs.
2025 Returns the state(string type) of the id if a single intent ID is
2026 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08002027 Returns a dictionary with intent IDs as the key and its
2028 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08002029 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08002030 intentId: intent ID (string type)
2031 intentsJson: parsed json object from the onos:intents api
2032 Returns:
2033 state = An intent's state- INSTALL,WITHDRAWN etc.
2034 stateDict = Dictionary of intent's state. intent ID as the keys and
2035 state as the values.
2036 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002037 try:
2038 state = "State is Undefined"
2039 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002040 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002041 else:
Jon Hallc6793552016-01-19 14:18:37 -08002042 rawJson = intentsJson
2043 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002044 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002045 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002046 if intentsId == intent[ 'id' ]:
2047 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002048 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002049 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2050 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002051 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002052 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002053 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002054 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002055 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002056 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002057 if intentsId[ i ] == intents[ 'id' ]:
2058 stateDict[ 'state' ] = intents[ 'state' ]
2059 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002060 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002061 break
Jon Hallefbd9792015-03-05 16:11:36 -08002062 if len( intentsId ) != len( dictList ):
2063 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002064 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002065 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002066 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002067 return None
Jon Hallc6793552016-01-19 14:18:37 -08002068 except ( TypeError, ValueError ):
2069 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 return None
2071 except pexpect.EOF:
2072 main.log.error( self.name + ": EOF exception found" )
2073 main.log.error( self.name + ": " + self.handle.before )
2074 main.cleanup()
2075 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002076 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002078 main.cleanup()
2079 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002080
kelvin-onlabf512e942015-06-08 19:42:59 -07002081 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002082 """
2083 Description:
2084 Check intents state
2085 Required:
2086 intentsId - List of intents ID to be checked
2087 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002088 expectedState - Check the expected state(s) of each intents
2089 state in the list.
2090 *NOTE: You can pass in a list of expected state,
2091 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002092 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002093 Returns main.TRUE only if all intent are the same as expected states
2094 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002095 """
2096 try:
2097 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002098 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002099 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002100 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002101 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002102 "getting intents state" )
2103 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002104
2105 if isinstance( expectedState, types.StringType ):
2106 for intents in intentsDict:
2107 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002108 main.log.debug( self.name + " : Intent ID - " +
2109 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002110 " actual state = " +
2111 intents.get( 'state' )
2112 + " does not equal expected state = "
2113 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002114 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002115
2116 elif isinstance( expectedState, types.ListType ):
2117 for intents in intentsDict:
2118 if not any( state == intents.get( 'state' ) for state in
2119 expectedState ):
2120 main.log.debug( self.name + " : Intent ID - " +
2121 intents.get( 'id' ) +
2122 " actual state = " +
2123 intents.get( 'state' ) +
2124 " does not equal expected states = "
2125 + str( expectedState ) )
2126 returnValue = main.FALSE
2127
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002128 if returnValue == main.TRUE:
2129 main.log.info( self.name + ": All " +
2130 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002131 " intents are in " + str( expectedState ) +
2132 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 return returnValue
2134 except TypeError:
2135 main.log.exception( self.name + ": Object not as expected" )
2136 return None
2137 except pexpect.EOF:
2138 main.log.error( self.name + ": EOF exception found" )
2139 main.log.error( self.name + ": " + self.handle.before )
2140 main.cleanup()
2141 main.exit()
2142 except Exception:
2143 main.log.exception( self.name + ": Uncaught exception!" )
2144 main.cleanup()
2145 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002146
GlennRCed771242016-01-13 17:02:47 -08002147 def checkIntentSummary( self, timeout=60 ):
2148 """
2149 Description:
2150 Check the number of installed intents.
2151 Optional:
2152 timeout - the timeout for pexcept
2153 Return:
2154 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2155 , otherwise, returns main.FALSE.
2156 """
2157
2158 try:
2159 cmd = "intents -s -j"
2160
2161 # Check response if something wrong
2162 response = self.sendline( cmd, timeout=timeout )
2163 if response == None:
2164 return main.False
2165 response = json.loads( response )
2166
2167 # get total and installed number, see if they are match
2168 allState = response.get( 'all' )
2169 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002170 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002171 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002172 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002173 return main.FALSE
2174
Jon Hallc6793552016-01-19 14:18:37 -08002175 except ( TypeError, ValueError ):
2176 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
2181 main.cleanup()
2182 main.exit()
2183 except Exception:
2184 main.log.exception( self.name + ": Uncaught exception!" )
2185 main.cleanup()
2186 main.exit()
2187
2188 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002189 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002190 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002191 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002192 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002193 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002194 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002195 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002196 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002197 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002198 cmdStr += " -j "
2199 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002200 handle = self.sendline( cmdStr, timeout=timeout )
2201 assert "Command not found:" not in handle, handle
2202 if re.search( "Error:", handle ):
2203 main.log.error( self.name + ": flows() response: " +
2204 str( handle ) )
2205 return handle
2206 except AssertionError:
2207 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002208 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002209 except TypeError:
2210 main.log.exception( self.name + ": Object not as expected" )
2211 return None
Jon Hallc6793552016-01-19 14:18:37 -08002212 except pexpect.TIMEOUT:
2213 main.log.error( self.name + ": ONOS timeout" )
2214 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002215 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002216 main.log.error( self.name + ": EOF exception found" )
2217 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002218 main.cleanup()
2219 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002220 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002221 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002222 main.cleanup()
2223 main.exit()
2224
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002225 def checkFlowCount(self, min=0, timeout=60 ):
2226 count = int(self.getTotalFlowsNum( timeout=timeout ))
2227 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002228
Jon Hallc6793552016-01-19 14:18:37 -08002229 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002230 """
2231 Description:
GlennRCed771242016-01-13 17:02:47 -08002232 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002233 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2234 if the count of those states is 0, which means all current flows
2235 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002236 Optional:
GlennRCed771242016-01-13 17:02:47 -08002237 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002238 Return:
2239 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002240 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002241 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002242 """
2243 try:
GlennRCed771242016-01-13 17:02:47 -08002244 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2245 checkedStates = []
2246 statesCount = [0, 0, 0, 0]
2247 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002248 rawFlows = self.flows( state=s, timeout = timeout )
2249 checkedStates.append( json.loads( rawFlows ) )
2250 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002251 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002252 try:
2253 statesCount[i] += int( c.get( "flowCount" ) )
2254 except TypeError:
2255 main.log.exception( "Json object not as expected" )
2256 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002257
GlennRCed771242016-01-13 17:02:47 -08002258 # We want to count PENDING_ADD if isPENDING is true
2259 if isPENDING:
2260 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2261 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002262 else:
GlennRCed771242016-01-13 17:02:47 -08002263 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2264 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002265 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002266 except ( TypeError, ValueError ):
2267 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002268 return None
2269 except pexpect.EOF:
2270 main.log.error( self.name + ": EOF exception found" )
2271 main.log.error( self.name + ": " + self.handle.before )
2272 main.cleanup()
2273 main.exit()
2274 except Exception:
2275 main.log.exception( self.name + ": Uncaught exception!" )
2276 main.cleanup()
2277 main.exit()
2278
GlennRCed771242016-01-13 17:02:47 -08002279 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2280 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002281 """
andrewonlab87852b02014-11-19 18:44:19 -05002282 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002283 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002284 a specific point-to-point intent definition
2285 Required:
GlennRCed771242016-01-13 17:02:47 -08002286 * ingress: specify source dpid
2287 * egress: specify destination dpid
2288 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002289 Optional:
GlennRCed771242016-01-13 17:02:47 -08002290 * offset: the keyOffset is where the next batch of intents
2291 will be installed
2292 Returns: If failed to push test intents, it will returen None,
2293 if successful, return true.
2294 Timeout expection will return None,
2295 TypeError will return false
2296 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002297 """
andrewonlab87852b02014-11-19 18:44:19 -05002298 try:
GlennRCed771242016-01-13 17:02:47 -08002299 if background:
2300 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002301 else:
GlennRCed771242016-01-13 17:02:47 -08002302 back = ""
2303 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002304 ingress,
2305 egress,
2306 batchSize,
2307 offset,
2308 back )
GlennRCed771242016-01-13 17:02:47 -08002309 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002310 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002311 main.log.info( response )
2312 if response == None:
2313 return None
2314
2315 # TODO: We should handle if there is failure in installation
2316 return main.TRUE
2317
Jon Hallc6793552016-01-19 14:18:37 -08002318 except AssertionError:
2319 main.log.exception( "" )
2320 return None
GlennRCed771242016-01-13 17:02:47 -08002321 except pexpect.TIMEOUT:
2322 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002323 return None
andrewonlab87852b02014-11-19 18:44:19 -05002324 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002325 main.log.error( self.name + ": EOF exception found" )
2326 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002327 main.cleanup()
2328 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002329 except TypeError:
2330 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002331 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002332 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002333 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002334 main.cleanup()
2335 main.exit()
2336
YPZhangf6f14a02016-01-28 15:17:31 -08002337 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002338 """
2339 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002340 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002341 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002342 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002343 """
YPZhange3109a72016-02-02 11:25:37 -08002344
YPZhangb5d3f832016-01-23 22:54:26 -08002345 try:
YPZhange3109a72016-02-02 11:25:37 -08002346 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002347 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002348 totalFlows = self.sendline( cmd, timeout=timeout )
2349
2350 if totalFlows == None:
2351 # if timeout, we will get total number of all flows, and subtract other states
2352 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2353 checkedStates = []
2354 totalFlows = 0
2355 statesCount = [0, 0, 0, 0]
2356
2357 # get total flows from summary
2358 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2359 totalFlows = int( response.get("flows") )
2360
2361 for s in states:
2362 rawFlows = self.flows( state=s, timeout = timeout )
2363 if rawFlows == None:
2364 # if timeout, return the total flows number from summary command
2365 return totalFlows
2366 checkedStates.append( json.loads( rawFlows ) )
2367
2368 # Calculate ADDED flows number, equal total subtracts others
2369 for i in range( len( states ) ):
2370 for c in checkedStates[i]:
2371 try:
2372 statesCount[i] += int( c.get( "flowCount" ) )
2373 except TypeError:
2374 main.log.exception( "Json object not as expected" )
2375 totalFlows = totalFlows - int( statesCount[i] )
2376 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2377
2378 return totalFlows
2379
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002380 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002381
YPZhangb5d3f832016-01-23 22:54:26 -08002382 except TypeError:
2383 main.log.exception( self.name + ": Object not as expected" )
2384 return None
2385 except pexpect.EOF:
2386 main.log.error( self.name + ": EOF exception found" )
2387 main.log.error( self.name + ": " + self.handle.before )
2388 main.cleanup()
2389 main.exit()
2390 except Exception:
2391 main.log.exception( self.name + ": Uncaught exception!" )
2392 main.cleanup()
2393 main.exit()
2394
2395 def getTotalIntentsNum( self ):
2396 """
2397 Description:
2398 Get the total number of intents, include every states.
2399 Return:
2400 The number of intents
2401 """
2402 try:
2403 cmd = "summary -j"
2404 response = self.sendline( cmd )
2405 if response == None:
2406 return -1
2407 response = json.loads( response )
2408 return int( response.get("intents") )
2409 except TypeError:
2410 main.log.exception( self.name + ": Object not as expected" )
2411 return None
2412 except pexpect.EOF:
2413 main.log.error( self.name + ": EOF exception found" )
2414 main.log.error( self.name + ": " + self.handle.before )
2415 main.cleanup()
2416 main.exit()
2417 except Exception:
2418 main.log.exception( self.name + ": Uncaught exception!" )
2419 main.cleanup()
2420 main.exit()
2421
kelvin-onlabd3b64892015-01-20 13:26:24 -08002422 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002423 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002424 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002425 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002427 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002428 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002429 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002430 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002431 cmdStr += " -j"
2432 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002433 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002434 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002435 except AssertionError:
2436 main.log.exception( "" )
2437 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002438 except TypeError:
2439 main.log.exception( self.name + ": Object not as expected" )
2440 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002442 main.log.error( self.name + ": EOF exception found" )
2443 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002444 main.cleanup()
2445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002447 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002448 main.cleanup()
2449 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002450
kelvin-onlabd3b64892015-01-20 13:26:24 -08002451 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002452 """
2453 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002454 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002455 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002456 """
andrewonlab867212a2014-10-22 20:13:38 -04002457 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002458 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002459 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002460 cmdStr += " -j"
2461 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002462 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002463 if handle:
2464 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002465 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002466 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002467 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002468 else:
2469 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002470 except AssertionError:
2471 main.log.exception( "" )
2472 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002473 except TypeError:
2474 main.log.exception( self.name + ": Object not as expected" )
2475 return None
andrewonlab867212a2014-10-22 20:13:38 -04002476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002477 main.log.error( self.name + ": EOF exception found" )
2478 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002479 main.cleanup()
2480 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002481 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002482 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002483 main.cleanup()
2484 main.exit()
2485
kelvin8ec71442015-01-15 16:57:00 -08002486 # Wrapper functions ****************
2487 # Wrapper functions use existing driver
2488 # functions and extends their use case.
2489 # For example, we may use the output of
2490 # a normal driver function, and parse it
2491 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002492
kelvin-onlabd3b64892015-01-20 13:26:24 -08002493 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002494 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002495 Description:
2496 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002497 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002498 try:
kelvin8ec71442015-01-15 16:57:00 -08002499 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002500 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002501 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002502
kelvin8ec71442015-01-15 16:57:00 -08002503 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002504 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2505 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002506 match = re.search('id=0x([\da-f]+),', intents)
2507 if match:
2508 tmpId = match.group()[3:-1]
2509 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002511
Jon Halld4d4b372015-01-28 16:02:41 -08002512 except TypeError:
2513 main.log.exception( self.name + ": Object not as expected" )
2514 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002516 main.log.error( self.name + ": EOF exception found" )
2517 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002518 main.cleanup()
2519 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002520 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002521 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002522 main.cleanup()
2523 main.exit()
2524
Jon Hall30b82fa2015-03-04 17:15:43 -08002525 def FlowAddedCount( self, deviceId ):
2526 """
2527 Determine the number of flow rules for the given device id that are
2528 in the added state
2529 """
2530 try:
2531 cmdStr = "flows any " + str( deviceId ) + " | " +\
2532 "grep 'state=ADDED' | wc -l"
2533 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002534 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002535 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002536 except AssertionError:
2537 main.log.exception( "" )
2538 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002539 except pexpect.EOF:
2540 main.log.error( self.name + ": EOF exception found" )
2541 main.log.error( self.name + ": " + self.handle.before )
2542 main.cleanup()
2543 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002544 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002545 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002546 main.cleanup()
2547 main.exit()
2548
kelvin-onlabd3b64892015-01-20 13:26:24 -08002549 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002550 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002551 Use 'devices' function to obtain list of all devices
2552 and parse the result to obtain a list of all device
2553 id's. Returns this list. Returns empty list if no
2554 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002555 List is ordered sequentially
2556
andrewonlab3e15ead2014-10-15 14:21:34 -04002557 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002558 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002559 the ids. By obtaining the list of device ids on the fly,
2560 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002561 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002562 try:
kelvin8ec71442015-01-15 16:57:00 -08002563 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002564 devicesStr = self.devices( jsonFormat=False )
2565 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002566
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002568 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 return idList
kelvin8ec71442015-01-15 16:57:00 -08002570
2571 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002573 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002574 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002575 # Split list further into arguments before and after string
2576 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002577 # append to idList
2578 for arg in tempList:
2579 idList.append( arg.split( "id=" )[ 1 ] )
2580 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002581
Jon Halld4d4b372015-01-28 16:02:41 -08002582 except TypeError:
2583 main.log.exception( self.name + ": Object not as expected" )
2584 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002585 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002586 main.log.error( self.name + ": EOF exception found" )
2587 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002588 main.cleanup()
2589 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002590 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002591 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002592 main.cleanup()
2593 main.exit()
2594
kelvin-onlabd3b64892015-01-20 13:26:24 -08002595 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002596 """
andrewonlab7c211572014-10-15 16:45:20 -04002597 Uses 'nodes' function to obtain list of all nodes
2598 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002599 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002600 Returns:
2601 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002602 """
andrewonlab7c211572014-10-15 16:45:20 -04002603 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002604 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002605 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002606 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002607 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002610 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002611 nodesJson = json.loads( nodesStr )
2612 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002613 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002614 except ( TypeError, ValueError ):
2615 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002616 return None
andrewonlab7c211572014-10-15 16:45:20 -04002617 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002618 main.log.error( self.name + ": EOF exception found" )
2619 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002620 main.cleanup()
2621 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002622 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002623 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002624 main.cleanup()
2625 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002626
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002628 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002629 Return the first device from the devices api whose 'id' contains 'dpid'
2630 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002631 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002632 try:
kelvin8ec71442015-01-15 16:57:00 -08002633 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002634 return None
2635 else:
kelvin8ec71442015-01-15 16:57:00 -08002636 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002637 rawDevices = self.devices()
2638 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002639 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002641 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2642 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002643 return device
2644 return None
Jon Hallc6793552016-01-19 14:18:37 -08002645 except ( TypeError, ValueError ):
2646 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002647 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002649 main.log.error( self.name + ": EOF exception found" )
2650 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002651 main.cleanup()
2652 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002653 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002654 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002655 main.cleanup()
2656 main.exit()
2657
You Wang24139872016-05-03 11:48:47 -07002658 def getTopology( self, topologyOutput ):
2659 """
2660 Definition:
2661 Loads a json topology output
2662 Return:
2663 topology = current ONOS topology
2664 """
2665 import json
2666 try:
2667 # either onos:topology or 'topology' will work in CLI
2668 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002669 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002670 return topology
2671 except pexpect.EOF:
2672 main.log.error( self.name + ": EOF exception found" )
2673 main.log.error( self.name + ": " + self.handle.before )
2674 main.cleanup()
2675 main.exit()
2676 except Exception:
2677 main.log.exception( self.name + ": Uncaught exception!" )
2678 main.cleanup()
2679 main.exit()
2680
2681 def checkStatus(
2682 self,
2683 topologyResult,
2684 numoswitch,
2685 numolink,
2686 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002687 """
Jon Hallefbd9792015-03-05 16:11:36 -08002688 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002689 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002690 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002691
You Wang24139872016-05-03 11:48:47 -07002692 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002693 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002694 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002695 logLevel = level to log to.
2696 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002697
Jon Hallefbd9792015-03-05 16:11:36 -08002698 Returns: main.TRUE if the number of switches and links are correct,
2699 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002700 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002701 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002702 try:
You Wang24139872016-05-03 11:48:47 -07002703 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002704 if topology == {}:
2705 return main.ERROR
2706 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002707 # Is the number of switches is what we expected
2708 devices = topology.get( 'devices', False )
2709 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002710 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002711 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002713 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002714 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002715 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002716 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002717 output = output + "The number of links and switches match "\
2718 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002719 result = main.TRUE
2720 else:
You Wang24139872016-05-03 11:48:47 -07002721 output = output + \
2722 "The number of links and switches does not match " + \
2723 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002724 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002725 output = output + "\n ONOS sees %i devices" % int( devices )
2726 output = output + " (%i expected) " % int( numoswitch )
2727 output = output + "and %i links " % int( links )
2728 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002729 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002730 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002732 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002733 else:
You Wang24139872016-05-03 11:48:47 -07002734 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002735 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002736 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002737 main.log.error( self.name + ": EOF exception found" )
2738 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002739 main.cleanup()
2740 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002741 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002742 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002743 main.cleanup()
2744 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002745
kelvin-onlabd3b64892015-01-20 13:26:24 -08002746 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002747 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002748 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002749 deviceId must be the id of a device as seen in the onos devices command
2750 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002751 role must be either master, standby, or none
2752
Jon Halle3f39ff2015-01-13 11:50:53 -08002753 Returns:
2754 main.TRUE or main.FALSE based on argument verification and
2755 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002756 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002757 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002758 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002759 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002760 cmdStr = "device-role " +\
2761 str( deviceId ) + " " +\
2762 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002763 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002764 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002765 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002766 if re.search( "Error", handle ):
2767 # end color output to escape any colours
2768 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002769 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002770 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002771 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002772 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002773 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002774 main.log.error( "Invalid 'role' given to device_role(). " +
2775 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002776 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002777 except AssertionError:
2778 main.log.exception( "" )
2779 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002780 except TypeError:
2781 main.log.exception( self.name + ": Object not as expected" )
2782 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002783 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002784 main.log.error( self.name + ": EOF exception found" )
2785 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002786 main.cleanup()
2787 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002788 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002789 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002790 main.cleanup()
2791 main.exit()
2792
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002794 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002795 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002796 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002797 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002798 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002799 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002800 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002802 cmdStr += " -j"
2803 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002804 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002805 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002806 except AssertionError:
2807 main.log.exception( "" )
2808 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002809 except TypeError:
2810 main.log.exception( self.name + ": Object not as expected" )
2811 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002813 main.log.error( self.name + ": EOF exception found" )
2814 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002815 main.cleanup()
2816 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002818 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002819 main.cleanup()
2820 main.exit()
2821
kelvin-onlabd3b64892015-01-20 13:26:24 -08002822 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002823 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002824 CLI command to get the current leader for the Election test application
2825 NOTE: Requires installation of the onos-app-election feature
2826 Returns: Node IP of the leader if one exists
2827 None if none exists
2828 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002829 """
Jon Hall94fd0472014-12-08 11:52:42 -08002830 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 cmdStr = "election-test-leader"
2832 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002833 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002834 # Leader
2835 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002836 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002837 nodeSearch = re.search( leaderPattern, response )
2838 if nodeSearch:
2839 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002840 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002841 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002842 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002843 # no leader
2844 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002845 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002846 nullSearch = re.search( nullPattern, response )
2847 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002848 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002849 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002850 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002851 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002852 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002853 if re.search( errorPattern, response ):
2854 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002855 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002856 return main.FALSE
2857 else:
Jon Hall390696c2015-05-05 17:13:41 -07002858 main.log.error( "Error in electionTestLeader on " + self.name +
2859 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002860 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002861 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002862 except AssertionError:
2863 main.log.exception( "" )
2864 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002865 except TypeError:
2866 main.log.exception( self.name + ": Object not as expected" )
2867 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002868 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002869 main.log.error( self.name + ": EOF exception found" )
2870 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002871 main.cleanup()
2872 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002873 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002874 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002875 main.cleanup()
2876 main.exit()
2877
kelvin-onlabd3b64892015-01-20 13:26:24 -08002878 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002879 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002880 CLI command to run for leadership of the Election test application.
2881 NOTE: Requires installation of the onos-app-election feature
2882 Returns: Main.TRUE on success
2883 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002884 """
Jon Hall94fd0472014-12-08 11:52:42 -08002885 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002886 cmdStr = "election-test-run"
2887 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002888 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002889 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002890 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002891 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002892 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002893 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002894 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002895 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002896 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002897 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002898 errorPattern = "Command\snot\sfound"
2899 if re.search( errorPattern, response ):
2900 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002901 return main.FALSE
2902 else:
Jon Hall390696c2015-05-05 17:13:41 -07002903 main.log.error( "Error in electionTestRun on " + self.name +
2904 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002905 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002906 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002907 except AssertionError:
2908 main.log.exception( "" )
2909 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002910 except TypeError:
2911 main.log.exception( self.name + ": Object not as expected" )
2912 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002913 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002914 main.log.error( self.name + ": EOF exception found" )
2915 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002916 main.cleanup()
2917 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002918 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002919 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002920 main.cleanup()
2921 main.exit()
2922
kelvin-onlabd3b64892015-01-20 13:26:24 -08002923 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002924 """
Jon Hall94fd0472014-12-08 11:52:42 -08002925 * CLI command to withdraw the local node from leadership election for
2926 * the Election test application.
2927 #NOTE: Requires installation of the onos-app-election feature
2928 Returns: Main.TRUE on success
2929 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002930 """
Jon Hall94fd0472014-12-08 11:52:42 -08002931 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002932 cmdStr = "election-test-withdraw"
2933 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002934 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002935 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002936 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002937 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002938 if re.search( successPattern, response ):
2939 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002940 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002941 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002942 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002943 errorPattern = "Command\snot\sfound"
2944 if re.search( errorPattern, response ):
2945 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002946 return main.FALSE
2947 else:
Jon Hall390696c2015-05-05 17:13:41 -07002948 main.log.error( "Error in electionTestWithdraw on " +
2949 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002950 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002951 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002952 except AssertionError:
2953 main.log.exception( "" )
2954 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002955 except TypeError:
2956 main.log.exception( self.name + ": Object not as expected" )
2957 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002959 main.log.error( self.name + ": EOF exception found" )
2960 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002961 main.cleanup()
2962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002964 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002965 main.cleanup()
2966 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002967
kelvin8ec71442015-01-15 16:57:00 -08002968 def getDevicePortsEnabledCount( self, dpid ):
2969 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002970 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002971 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002972 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002973 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002974 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2975 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002976 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002977 if re.search( "No such device", output ):
2978 main.log.error( "Error in getting ports" )
2979 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002980 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002981 return output
Jon Hallc6793552016-01-19 14:18:37 -08002982 except AssertionError:
2983 main.log.exception( "" )
2984 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002985 except TypeError:
2986 main.log.exception( self.name + ": Object not as expected" )
2987 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002988 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002989 main.log.error( self.name + ": EOF exception found" )
2990 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002991 main.cleanup()
2992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002994 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002995 main.cleanup()
2996 main.exit()
2997
kelvin8ec71442015-01-15 16:57:00 -08002998 def getDeviceLinksActiveCount( self, dpid ):
2999 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003000 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003001 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003002 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003003 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3005 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003006 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003007 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 main.log.error( "Error in getting ports " )
3009 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003010 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003011 return output
Jon Hallc6793552016-01-19 14:18:37 -08003012 except AssertionError:
3013 main.log.exception( "" )
3014 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003015 except TypeError:
3016 main.log.exception( self.name + ": Object not as expected" )
3017 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003018 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003019 main.log.error( self.name + ": EOF exception found" )
3020 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003021 main.cleanup()
3022 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003023 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003024 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003025 main.cleanup()
3026 main.exit()
3027
kelvin8ec71442015-01-15 16:57:00 -08003028 def getAllIntentIds( self ):
3029 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003030 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003031 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003032 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003033 cmdStr = "onos:intents | grep id="
3034 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003035 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003036 if re.search( "Error", output ):
3037 main.log.error( "Error in getting ports" )
3038 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003039 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 return output
Jon Hallc6793552016-01-19 14:18:37 -08003041 except AssertionError:
3042 main.log.exception( "" )
3043 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003044 except TypeError:
3045 main.log.exception( self.name + ": Object not as expected" )
3046 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003048 main.log.error( self.name + ": EOF exception found" )
3049 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003050 main.cleanup()
3051 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003052 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003053 main.log.exception( self.name + ": Uncaught exception!" )
3054 main.cleanup()
3055 main.exit()
3056
Jon Hall73509952015-02-24 16:42:56 -08003057 def intentSummary( self ):
3058 """
Jon Hallefbd9792015-03-05 16:11:36 -08003059 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003060 """
3061 try:
3062 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003063 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003064 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003065 states.append( intent.get( 'state', None ) )
3066 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003067 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003068 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003069 except ( TypeError, ValueError ):
3070 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003071 return None
3072 except pexpect.EOF:
3073 main.log.error( self.name + ": EOF exception found" )
3074 main.log.error( self.name + ": " + self.handle.before )
3075 main.cleanup()
3076 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003077 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003078 main.log.exception( self.name + ": Uncaught exception!" )
3079 main.cleanup()
3080 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003081
Jon Hall61282e32015-03-19 11:34:11 -07003082 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003083 """
3084 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003085 Optional argument:
3086 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003087 """
Jon Hall63604932015-02-26 17:09:50 -08003088 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003089 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003090 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003091 cmdStr += " -j"
3092 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003093 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003094 return output
Jon Hallc6793552016-01-19 14:18:37 -08003095 except AssertionError:
3096 main.log.exception( "" )
3097 return None
Jon Hall63604932015-02-26 17:09:50 -08003098 except TypeError:
3099 main.log.exception( self.name + ": Object not as expected" )
3100 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003101 except pexpect.EOF:
3102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
3104 main.cleanup()
3105 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003106 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003107 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003108 main.cleanup()
3109 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003110
acsmarsa4a4d1e2015-07-10 16:01:24 -07003111 def leaderCandidates( self, jsonFormat=True ):
3112 """
3113 Returns the output of the leaders -c command.
3114 Optional argument:
3115 * jsonFormat - boolean indicating if you want output in json
3116 """
3117 try:
3118 cmdStr = "onos:leaders -c"
3119 if jsonFormat:
3120 cmdStr += " -j"
3121 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003122 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003123 return output
Jon Hallc6793552016-01-19 14:18:37 -08003124 except AssertionError:
3125 main.log.exception( "" )
3126 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003127 except TypeError:
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return None
3130 except pexpect.EOF:
3131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
3133 main.cleanup()
3134 main.exit()
3135 except Exception:
3136 main.log.exception( self.name + ": Uncaught exception!" )
3137 main.cleanup()
3138 main.exit()
3139
Jon Hallc6793552016-01-19 14:18:37 -08003140 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003141 """
3142 Returns a list in format [leader,candidate1,candidate2,...] for a given
3143 topic parameter and an empty list if the topic doesn't exist
3144 If no leader is elected leader in the returned list will be "none"
3145 Returns None if there is a type error processing the json object
3146 """
3147 try:
Jon Hall6e709752016-02-01 13:38:46 -08003148 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003149 rawOutput = self.sendline( cmdStr )
3150 assert "Command not found:" not in rawOutput, rawOutput
3151 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003152 results = []
3153 for dict in output:
3154 if dict["topic"] == topic:
3155 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003156 candidates = re.split( ", ", dict["candidates"][1:-1] )
3157 results.append( leader )
3158 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003159 return results
Jon Hallc6793552016-01-19 14:18:37 -08003160 except AssertionError:
3161 main.log.exception( "" )
3162 return None
3163 except ( TypeError, ValueError ):
3164 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003165 return None
3166 except pexpect.EOF:
3167 main.log.error( self.name + ": EOF exception found" )
3168 main.log.error( self.name + ": " + self.handle.before )
3169 main.cleanup()
3170 main.exit()
3171 except Exception:
3172 main.log.exception( self.name + ": Uncaught exception!" )
3173 main.cleanup()
3174 main.exit()
3175
Jon Hall61282e32015-03-19 11:34:11 -07003176 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003177 """
3178 Returns the output of the intent Pending map.
3179 """
Jon Hall63604932015-02-26 17:09:50 -08003180 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003181 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003182 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003183 cmdStr += " -j"
3184 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003185 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003186 return output
Jon Hallc6793552016-01-19 14:18:37 -08003187 except AssertionError:
3188 main.log.exception( "" )
3189 return None
Jon Hall63604932015-02-26 17:09:50 -08003190 except TypeError:
3191 main.log.exception( self.name + ": Object not as expected" )
3192 return None
3193 except pexpect.EOF:
3194 main.log.error( self.name + ": EOF exception found" )
3195 main.log.error( self.name + ": " + self.handle.before )
3196 main.cleanup()
3197 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003198 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003199 main.log.exception( self.name + ": Uncaught exception!" )
3200 main.cleanup()
3201 main.exit()
3202
Jon Hall61282e32015-03-19 11:34:11 -07003203 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003204 """
3205 Returns the output of the raft partitions command for ONOS.
3206 """
Jon Hall61282e32015-03-19 11:34:11 -07003207 # Sample JSON
3208 # {
3209 # "leader": "tcp://10.128.30.11:7238",
3210 # "members": [
3211 # "tcp://10.128.30.11:7238",
3212 # "tcp://10.128.30.17:7238",
3213 # "tcp://10.128.30.13:7238",
3214 # ],
3215 # "name": "p1",
3216 # "term": 3
3217 # },
Jon Hall63604932015-02-26 17:09:50 -08003218 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003219 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003220 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003221 cmdStr += " -j"
3222 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003223 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003224 return output
Jon Hallc6793552016-01-19 14:18:37 -08003225 except AssertionError:
3226 main.log.exception( "" )
3227 return None
Jon Hall63604932015-02-26 17:09:50 -08003228 except TypeError:
3229 main.log.exception( self.name + ": Object not as expected" )
3230 return None
3231 except pexpect.EOF:
3232 main.log.error( self.name + ": EOF exception found" )
3233 main.log.error( self.name + ": " + self.handle.before )
3234 main.cleanup()
3235 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003236 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003237 main.log.exception( self.name + ": Uncaught exception!" )
3238 main.cleanup()
3239 main.exit()
3240
Jon Hallbe379602015-03-24 13:39:32 -07003241 def apps( self, jsonFormat=True ):
3242 """
3243 Returns the output of the apps command for ONOS. This command lists
3244 information about installed ONOS applications
3245 """
3246 # Sample JSON object
3247 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3248 # "description":"ONOS OpenFlow protocol southbound providers",
3249 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3250 # "features":"[onos-openflow]","state":"ACTIVE"}]
3251 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003252 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003253 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003254 cmdStr += " -j"
3255 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003256 assert "Command not found:" not in output, output
3257 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003258 return output
Jon Hallbe379602015-03-24 13:39:32 -07003259 # FIXME: look at specific exceptions/Errors
3260 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003261 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003262 return None
3263 except TypeError:
3264 main.log.exception( self.name + ": Object not as expected" )
3265 return None
3266 except pexpect.EOF:
3267 main.log.error( self.name + ": EOF exception found" )
3268 main.log.error( self.name + ": " + self.handle.before )
3269 main.cleanup()
3270 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003271 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003272 main.log.exception( self.name + ": Uncaught exception!" )
3273 main.cleanup()
3274 main.exit()
3275
Jon Hall146f1522015-03-24 15:33:24 -07003276 def appStatus( self, appName ):
3277 """
3278 Uses the onos:apps cli command to return the status of an application.
3279 Returns:
3280 "ACTIVE" - If app is installed and activated
3281 "INSTALLED" - If app is installed and deactivated
3282 "UNINSTALLED" - If app is not installed
3283 None - on error
3284 """
Jon Hall146f1522015-03-24 15:33:24 -07003285 try:
3286 if not isinstance( appName, types.StringType ):
3287 main.log.error( self.name + ".appStatus(): appName must be" +
3288 " a string" )
3289 return None
3290 output = self.apps( jsonFormat=True )
3291 appsJson = json.loads( output )
3292 state = None
3293 for app in appsJson:
3294 if appName == app.get('name'):
3295 state = app.get('state')
3296 break
3297 if state == "ACTIVE" or state == "INSTALLED":
3298 return state
3299 elif state is None:
3300 return "UNINSTALLED"
3301 elif state:
3302 main.log.error( "Unexpected state from 'onos:apps': " +
3303 str( state ) )
3304 return state
Jon Hallc6793552016-01-19 14:18:37 -08003305 except ( TypeError, ValueError ):
3306 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003307 return None
3308 except pexpect.EOF:
3309 main.log.error( self.name + ": EOF exception found" )
3310 main.log.error( self.name + ": " + self.handle.before )
3311 main.cleanup()
3312 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003313 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003314 main.log.exception( self.name + ": Uncaught exception!" )
3315 main.cleanup()
3316 main.exit()
3317
Jon Hallbe379602015-03-24 13:39:32 -07003318 def app( self, appName, option ):
3319 """
3320 Interacts with the app command for ONOS. This command manages
3321 application inventory.
3322 """
Jon Hallbe379602015-03-24 13:39:32 -07003323 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003324 # Validate argument types
3325 valid = True
3326 if not isinstance( appName, types.StringType ):
3327 main.log.error( self.name + ".app(): appName must be a " +
3328 "string" )
3329 valid = False
3330 if not isinstance( option, types.StringType ):
3331 main.log.error( self.name + ".app(): option must be a string" )
3332 valid = False
3333 if not valid:
3334 return main.FALSE
3335 # Validate Option
3336 option = option.lower()
3337 # NOTE: Install may become a valid option
3338 if option == "activate":
3339 pass
3340 elif option == "deactivate":
3341 pass
3342 elif option == "uninstall":
3343 pass
3344 else:
3345 # Invalid option
3346 main.log.error( "The ONOS app command argument only takes " +
3347 "the values: (activate|deactivate|uninstall)" +
3348 "; was given '" + option + "'")
3349 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003350 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003351 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003352 if "Error executing command" in output:
3353 main.log.error( "Error in processing onos:app command: " +
3354 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003355 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003356 elif "No such application" in output:
3357 main.log.error( "The application '" + appName +
3358 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003359 return main.FALSE
3360 elif "Command not found:" in output:
3361 main.log.error( "Error in processing onos:app command: " +
3362 str( output ) )
3363 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003364 elif "Unsupported command:" in output:
3365 main.log.error( "Incorrect command given to 'app': " +
3366 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003367 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003368 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003369 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003370 return main.TRUE
3371 except TypeError:
3372 main.log.exception( self.name + ": Object not as expected" )
3373 return main.ERROR
3374 except pexpect.EOF:
3375 main.log.error( self.name + ": EOF exception found" )
3376 main.log.error( self.name + ": " + self.handle.before )
3377 main.cleanup()
3378 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003379 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003380 main.log.exception( self.name + ": Uncaught exception!" )
3381 main.cleanup()
3382 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003383
Jon Hallbd16b922015-03-26 17:53:15 -07003384 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003385 """
3386 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003387 appName is the hierarchical app name, not the feature name
3388 If check is True, method will check the status of the app after the
3389 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003390 Returns main.TRUE if the command was successfully sent
3391 main.FALSE if the cli responded with an error or given
3392 incorrect input
3393 """
3394 try:
3395 if not isinstance( appName, types.StringType ):
3396 main.log.error( self.name + ".activateApp(): appName must be" +
3397 " a string" )
3398 return main.FALSE
3399 status = self.appStatus( appName )
3400 if status == "INSTALLED":
3401 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003402 if check and response == main.TRUE:
3403 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003404 status = self.appStatus( appName )
3405 if status == "ACTIVE":
3406 return main.TRUE
3407 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003408 main.log.debug( "The state of application " +
3409 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003410 time.sleep( 1 )
3411 return main.FALSE
3412 else: # not 'check' or command didn't succeed
3413 return response
Jon Hall146f1522015-03-24 15:33:24 -07003414 elif status == "ACTIVE":
3415 return main.TRUE
3416 elif status == "UNINSTALLED":
3417 main.log.error( self.name + ": Tried to activate the " +
3418 "application '" + appName + "' which is not " +
3419 "installed." )
3420 else:
3421 main.log.error( "Unexpected return value from appStatus: " +
3422 str( status ) )
3423 return main.ERROR
3424 except TypeError:
3425 main.log.exception( self.name + ": Object not as expected" )
3426 return main.ERROR
3427 except pexpect.EOF:
3428 main.log.error( self.name + ": EOF exception found" )
3429 main.log.error( self.name + ": " + self.handle.before )
3430 main.cleanup()
3431 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003432 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003433 main.log.exception( self.name + ": Uncaught exception!" )
3434 main.cleanup()
3435 main.exit()
3436
Jon Hallbd16b922015-03-26 17:53:15 -07003437 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003438 """
3439 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003440 appName is the hierarchical app name, not the feature name
3441 If check is True, method will check the status of the app after the
3442 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003443 Returns main.TRUE if the command was successfully sent
3444 main.FALSE if the cli responded with an error or given
3445 incorrect input
3446 """
3447 try:
3448 if not isinstance( appName, types.StringType ):
3449 main.log.error( self.name + ".deactivateApp(): appName must " +
3450 "be a string" )
3451 return main.FALSE
3452 status = self.appStatus( appName )
3453 if status == "INSTALLED":
3454 return main.TRUE
3455 elif status == "ACTIVE":
3456 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003457 if check and response == main.TRUE:
3458 for i in range(10): # try 10 times then give up
3459 status = self.appStatus( appName )
3460 if status == "INSTALLED":
3461 return main.TRUE
3462 else:
3463 time.sleep( 1 )
3464 return main.FALSE
3465 else: # not check or command didn't succeed
3466 return response
Jon Hall146f1522015-03-24 15:33:24 -07003467 elif status == "UNINSTALLED":
3468 main.log.warn( self.name + ": Tried to deactivate the " +
3469 "application '" + appName + "' which is not " +
3470 "installed." )
3471 return main.TRUE
3472 else:
3473 main.log.error( "Unexpected return value from appStatus: " +
3474 str( status ) )
3475 return main.ERROR
3476 except TypeError:
3477 main.log.exception( self.name + ": Object not as expected" )
3478 return main.ERROR
3479 except pexpect.EOF:
3480 main.log.error( self.name + ": EOF exception found" )
3481 main.log.error( self.name + ": " + self.handle.before )
3482 main.cleanup()
3483 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003484 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003485 main.log.exception( self.name + ": Uncaught exception!" )
3486 main.cleanup()
3487 main.exit()
3488
Jon Hallbd16b922015-03-26 17:53:15 -07003489 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003490 """
3491 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003492 appName is the hierarchical app name, not the feature name
3493 If check is True, method will check the status of the app after the
3494 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003495 Returns main.TRUE if the command was successfully sent
3496 main.FALSE if the cli responded with an error or given
3497 incorrect input
3498 """
3499 # TODO: check with Thomas about the state machine for apps
3500 try:
3501 if not isinstance( appName, types.StringType ):
3502 main.log.error( self.name + ".uninstallApp(): appName must " +
3503 "be a string" )
3504 return main.FALSE
3505 status = self.appStatus( appName )
3506 if status == "INSTALLED":
3507 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003508 if check and response == main.TRUE:
3509 for i in range(10): # try 10 times then give up
3510 status = self.appStatus( appName )
3511 if status == "UNINSTALLED":
3512 return main.TRUE
3513 else:
3514 time.sleep( 1 )
3515 return main.FALSE
3516 else: # not check or command didn't succeed
3517 return response
Jon Hall146f1522015-03-24 15:33:24 -07003518 elif status == "ACTIVE":
3519 main.log.warn( self.name + ": Tried to uninstall the " +
3520 "application '" + appName + "' which is " +
3521 "currently active." )
3522 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003523 if check and response == main.TRUE:
3524 for i in range(10): # try 10 times then give up
3525 status = self.appStatus( appName )
3526 if status == "UNINSTALLED":
3527 return main.TRUE
3528 else:
3529 time.sleep( 1 )
3530 return main.FALSE
3531 else: # not check or command didn't succeed
3532 return response
Jon Hall146f1522015-03-24 15:33:24 -07003533 elif status == "UNINSTALLED":
3534 return main.TRUE
3535 else:
3536 main.log.error( "Unexpected return value from appStatus: " +
3537 str( status ) )
3538 return main.ERROR
3539 except TypeError:
3540 main.log.exception( self.name + ": Object not as expected" )
3541 return main.ERROR
3542 except pexpect.EOF:
3543 main.log.error( self.name + ": EOF exception found" )
3544 main.log.error( self.name + ": " + self.handle.before )
3545 main.cleanup()
3546 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003547 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003548 main.log.exception( self.name + ": Uncaught exception!" )
3549 main.cleanup()
3550 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003551
3552 def appIDs( self, jsonFormat=True ):
3553 """
3554 Show the mappings between app id and app names given by the 'app-ids'
3555 cli command
3556 """
3557 try:
3558 cmdStr = "app-ids"
3559 if jsonFormat:
3560 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003561 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003562 assert "Command not found:" not in output, output
3563 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003564 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003565 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003566 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003567 return None
3568 except TypeError:
3569 main.log.exception( self.name + ": Object not as expected" )
3570 return None
3571 except pexpect.EOF:
3572 main.log.error( self.name + ": EOF exception found" )
3573 main.log.error( self.name + ": " + self.handle.before )
3574 main.cleanup()
3575 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003576 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003577 main.log.exception( self.name + ": Uncaught exception!" )
3578 main.cleanup()
3579 main.exit()
3580
3581 def appToIDCheck( self ):
3582 """
3583 This method will check that each application's ID listed in 'apps' is
3584 the same as the ID listed in 'app-ids'. The check will also check that
3585 there are no duplicate IDs issued. Note that an app ID should be
3586 a globaly unique numerical identifier for app/app-like features. Once
3587 an ID is registered, the ID is never freed up so that if an app is
3588 reinstalled it will have the same ID.
3589
3590 Returns: main.TRUE if the check passes and
3591 main.FALSE if the check fails or
3592 main.ERROR if there is some error in processing the test
3593 """
3594 try:
Jon Hall390696c2015-05-05 17:13:41 -07003595 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003596 rawJson = self.appIDs( jsonFormat=True )
3597 if rawJson:
3598 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003599 else:
Jon Hallc6793552016-01-19 14:18:37 -08003600 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003601 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003602 rawJson = self.apps( jsonFormat=True )
3603 if rawJson:
3604 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003605 else:
Jon Hallc6793552016-01-19 14:18:37 -08003606 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003607 bail = True
3608 if bail:
3609 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003610 result = main.TRUE
3611 for app in apps:
3612 appID = app.get( 'id' )
3613 if appID is None:
3614 main.log.error( "Error parsing app: " + str( app ) )
3615 result = main.FALSE
3616 appName = app.get( 'name' )
3617 if appName is None:
3618 main.log.error( "Error parsing app: " + str( app ) )
3619 result = main.FALSE
3620 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003621 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003622 # main.log.debug( "Comparing " + str( app ) + " to " +
3623 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003624 if not current: # if ids doesn't have this id
3625 result = main.FALSE
3626 main.log.error( "'app-ids' does not have the ID for " +
3627 str( appName ) + " that apps does." )
3628 elif len( current ) > 1:
3629 # there is more than one app with this ID
3630 result = main.FALSE
3631 # We will log this later in the method
3632 elif not current[0][ 'name' ] == appName:
3633 currentName = current[0][ 'name' ]
3634 result = main.FALSE
3635 main.log.error( "'app-ids' has " + str( currentName ) +
3636 " registered under id:" + str( appID ) +
3637 " but 'apps' has " + str( appName ) )
3638 else:
3639 pass # id and name match!
3640 # now make sure that app-ids has no duplicates
3641 idsList = []
3642 namesList = []
3643 for item in ids:
3644 idsList.append( item[ 'id' ] )
3645 namesList.append( item[ 'name' ] )
3646 if len( idsList ) != len( set( idsList ) ) or\
3647 len( namesList ) != len( set( namesList ) ):
3648 main.log.error( "'app-ids' has some duplicate entries: \n"
3649 + json.dumps( ids,
3650 sort_keys=True,
3651 indent=4,
3652 separators=( ',', ': ' ) ) )
3653 result = main.FALSE
3654 return result
Jon Hallc6793552016-01-19 14:18:37 -08003655 except ( TypeError, ValueError ):
3656 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003657 return main.ERROR
3658 except pexpect.EOF:
3659 main.log.error( self.name + ": EOF exception found" )
3660 main.log.error( self.name + ": " + self.handle.before )
3661 main.cleanup()
3662 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003663 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003664 main.log.exception( self.name + ": Uncaught exception!" )
3665 main.cleanup()
3666 main.exit()
3667
Jon Hallfb760a02015-04-13 15:35:03 -07003668 def getCfg( self, component=None, propName=None, short=False,
3669 jsonFormat=True ):
3670 """
3671 Get configuration settings from onos cli
3672 Optional arguments:
3673 component - Optionally only list configurations for a specific
3674 component. If None, all components with configurations
3675 are displayed. Case Sensitive string.
3676 propName - If component is specified, propName option will show
3677 only this specific configuration from that component.
3678 Case Sensitive string.
3679 jsonFormat - Returns output as json. Note that this will override
3680 the short option
3681 short - Short, less verbose, version of configurations.
3682 This is overridden by the json option
3683 returns:
3684 Output from cli as a string or None on error
3685 """
3686 try:
3687 baseStr = "cfg"
3688 cmdStr = " get"
3689 componentStr = ""
3690 if component:
3691 componentStr += " " + component
3692 if propName:
3693 componentStr += " " + propName
3694 if jsonFormat:
3695 baseStr += " -j"
3696 elif short:
3697 baseStr += " -s"
3698 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003699 assert "Command not found:" not in output, output
3700 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003701 return output
3702 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003703 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003704 return None
3705 except TypeError:
3706 main.log.exception( self.name + ": Object not as expected" )
3707 return None
3708 except pexpect.EOF:
3709 main.log.error( self.name + ": EOF exception found" )
3710 main.log.error( self.name + ": " + self.handle.before )
3711 main.cleanup()
3712 main.exit()
3713 except Exception:
3714 main.log.exception( self.name + ": Uncaught exception!" )
3715 main.cleanup()
3716 main.exit()
3717
3718 def setCfg( self, component, propName, value=None, check=True ):
3719 """
3720 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003721 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003722 component - The case sensitive name of the component whose
3723 property is to be set
3724 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003725 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003726 value - The value to set the property to. If None, will unset the
3727 property and revert it to it's default value(if applicable)
3728 check - Boolean, Check whether the option was successfully set this
3729 only applies when a value is given.
3730 returns:
3731 main.TRUE on success or main.FALSE on failure. If check is False,
3732 will return main.TRUE unless there is an error
3733 """
3734 try:
3735 baseStr = "cfg"
3736 cmdStr = " set " + str( component ) + " " + str( propName )
3737 if value is not None:
3738 cmdStr += " " + str( value )
3739 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003740 assert "Command not found:" not in output, output
3741 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003742 if value and check:
3743 results = self.getCfg( component=str( component ),
3744 propName=str( propName ),
3745 jsonFormat=True )
3746 # Check if current value is what we just set
3747 try:
3748 jsonOutput = json.loads( results )
3749 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003750 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003751 main.log.exception( "Error parsing cfg output" )
3752 main.log.error( "output:" + repr( results ) )
3753 return main.FALSE
3754 if current == str( value ):
3755 return main.TRUE
3756 return main.FALSE
3757 return main.TRUE
3758 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003759 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003760 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003761 except ( TypeError, ValueError ):
3762 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003763 return main.FALSE
3764 except pexpect.EOF:
3765 main.log.error( self.name + ": EOF exception found" )
3766 main.log.error( self.name + ": " + self.handle.before )
3767 main.cleanup()
3768 main.exit()
3769 except Exception:
3770 main.log.exception( self.name + ": Uncaught exception!" )
3771 main.cleanup()
3772 main.exit()
3773
Jon Hall390696c2015-05-05 17:13:41 -07003774 def setTestAdd( self, setName, values ):
3775 """
3776 CLI command to add elements to a distributed set.
3777 Arguments:
3778 setName - The name of the set to add to.
3779 values - The value(s) to add to the set, space seperated.
3780 Example usages:
3781 setTestAdd( "set1", "a b c" )
3782 setTestAdd( "set2", "1" )
3783 returns:
3784 main.TRUE on success OR
3785 main.FALSE if elements were already in the set OR
3786 main.ERROR on error
3787 """
3788 try:
3789 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3790 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003791 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003792 try:
3793 # TODO: Maybe make this less hardcoded
3794 # ConsistentMap Exceptions
3795 assert "org.onosproject.store.service" not in output
3796 # Node not leader
3797 assert "java.lang.IllegalStateException" not in output
3798 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003799 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003800 "command: " + str( output ) )
3801 retryTime = 30 # Conservative time, given by Madan
3802 main.log.info( "Waiting " + str( retryTime ) +
3803 "seconds before retrying." )
3804 time.sleep( retryTime ) # Due to change in mastership
3805 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003806 assert "Error executing command" not in output
3807 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3808 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3809 main.log.info( self.name + ": " + output )
3810 if re.search( positiveMatch, output):
3811 return main.TRUE
3812 elif re.search( negativeMatch, output):
3813 return main.FALSE
3814 else:
3815 main.log.error( self.name + ": setTestAdd did not" +
3816 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003817 main.log.debug( self.name + " actual: " + repr( output ) )
3818 return main.ERROR
3819 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003820 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003821 return main.ERROR
3822 except TypeError:
3823 main.log.exception( self.name + ": Object not as expected" )
3824 return main.ERROR
3825 except pexpect.EOF:
3826 main.log.error( self.name + ": EOF exception found" )
3827 main.log.error( self.name + ": " + self.handle.before )
3828 main.cleanup()
3829 main.exit()
3830 except Exception:
3831 main.log.exception( self.name + ": Uncaught exception!" )
3832 main.cleanup()
3833 main.exit()
3834
3835 def setTestRemove( self, setName, values, clear=False, retain=False ):
3836 """
3837 CLI command to remove elements from a distributed set.
3838 Required arguments:
3839 setName - The name of the set to remove from.
3840 values - The value(s) to remove from the set, space seperated.
3841 Optional arguments:
3842 clear - Clear all elements from the set
3843 retain - Retain only the given values. (intersection of the
3844 original set and the given set)
3845 returns:
3846 main.TRUE on success OR
3847 main.FALSE if the set was not changed OR
3848 main.ERROR on error
3849 """
3850 try:
3851 cmdStr = "set-test-remove "
3852 if clear:
3853 cmdStr += "-c " + str( setName )
3854 elif retain:
3855 cmdStr += "-r " + str( setName ) + " " + str( values )
3856 else:
3857 cmdStr += str( setName ) + " " + str( values )
3858 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003859 try:
3860 # TODO: Maybe make this less hardcoded
3861 # ConsistentMap Exceptions
3862 assert "org.onosproject.store.service" not in output
3863 # Node not leader
3864 assert "java.lang.IllegalStateException" not in output
3865 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003866 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003867 "command: " + str( output ) )
3868 retryTime = 30 # Conservative time, given by Madan
3869 main.log.info( "Waiting " + str( retryTime ) +
3870 "seconds before retrying." )
3871 time.sleep( retryTime ) # Due to change in mastership
3872 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003873 assert "Command not found:" not in output, output
3874 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003875 main.log.info( self.name + ": " + output )
3876 if clear:
3877 pattern = "Set " + str( setName ) + " cleared"
3878 if re.search( pattern, output ):
3879 return main.TRUE
3880 elif retain:
3881 positivePattern = str( setName ) + " was pruned to contain " +\
3882 "only elements of set \[(.*)\]"
3883 negativePattern = str( setName ) + " was not changed by " +\
3884 "retaining only elements of the set " +\
3885 "\[(.*)\]"
3886 if re.search( positivePattern, output ):
3887 return main.TRUE
3888 elif re.search( negativePattern, output ):
3889 return main.FALSE
3890 else:
3891 positivePattern = "\[(.*)\] was removed from the set " +\
3892 str( setName )
3893 if ( len( values.split() ) == 1 ):
3894 negativePattern = "\[(.*)\] was not in set " +\
3895 str( setName )
3896 else:
3897 negativePattern = "No element of \[(.*)\] was in set " +\
3898 str( setName )
3899 if re.search( positivePattern, output ):
3900 return main.TRUE
3901 elif re.search( negativePattern, output ):
3902 return main.FALSE
3903 main.log.error( self.name + ": setTestRemove did not" +
3904 " match expected output" )
3905 main.log.debug( self.name + " expected: " + pattern )
3906 main.log.debug( self.name + " actual: " + repr( output ) )
3907 return main.ERROR
3908 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003909 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003910 return main.ERROR
3911 except TypeError:
3912 main.log.exception( self.name + ": Object not as expected" )
3913 return main.ERROR
3914 except pexpect.EOF:
3915 main.log.error( self.name + ": EOF exception found" )
3916 main.log.error( self.name + ": " + self.handle.before )
3917 main.cleanup()
3918 main.exit()
3919 except Exception:
3920 main.log.exception( self.name + ": Uncaught exception!" )
3921 main.cleanup()
3922 main.exit()
3923
3924 def setTestGet( self, setName, values="" ):
3925 """
3926 CLI command to get the elements in a distributed set.
3927 Required arguments:
3928 setName - The name of the set to remove from.
3929 Optional arguments:
3930 values - The value(s) to check if in the set, space seperated.
3931 returns:
3932 main.ERROR on error OR
3933 A list of elements in the set if no optional arguments are
3934 supplied OR
3935 A tuple containing the list then:
3936 main.FALSE if the given values are not in the set OR
3937 main.TRUE if the given values are in the set OR
3938 """
3939 try:
3940 values = str( values ).strip()
3941 setName = str( setName ).strip()
3942 length = len( values.split() )
3943 containsCheck = None
3944 # Patterns to match
3945 setPattern = "\[(.*)\]"
3946 pattern = "Items in set " + setName + ":\n" + setPattern
3947 containsTrue = "Set " + setName + " contains the value " + values
3948 containsFalse = "Set " + setName + " did not contain the value " +\
3949 values
3950 containsAllTrue = "Set " + setName + " contains the the subset " +\
3951 setPattern
3952 containsAllFalse = "Set " + setName + " did not contain the the" +\
3953 " subset " + setPattern
3954
3955 cmdStr = "set-test-get "
3956 cmdStr += setName + " " + values
3957 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003958 try:
3959 # TODO: Maybe make this less hardcoded
3960 # ConsistentMap Exceptions
3961 assert "org.onosproject.store.service" not in output
3962 # Node not leader
3963 assert "java.lang.IllegalStateException" not in output
3964 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003965 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003966 "command: " + str( output ) )
3967 retryTime = 30 # Conservative time, given by Madan
3968 main.log.info( "Waiting " + str( retryTime ) +
3969 "seconds before retrying." )
3970 time.sleep( retryTime ) # Due to change in mastership
3971 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003972 assert "Command not found:" not in output, output
3973 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003974 main.log.info( self.name + ": " + output )
3975
3976 if length == 0:
3977 match = re.search( pattern, output )
3978 else: # if given values
3979 if length == 1: # Contains output
3980 patternTrue = pattern + "\n" + containsTrue
3981 patternFalse = pattern + "\n" + containsFalse
3982 else: # ContainsAll output
3983 patternTrue = pattern + "\n" + containsAllTrue
3984 patternFalse = pattern + "\n" + containsAllFalse
3985 matchTrue = re.search( patternTrue, output )
3986 matchFalse = re.search( patternFalse, output )
3987 if matchTrue:
3988 containsCheck = main.TRUE
3989 match = matchTrue
3990 elif matchFalse:
3991 containsCheck = main.FALSE
3992 match = matchFalse
3993 else:
3994 main.log.error( self.name + " setTestGet did not match " +\
3995 "expected output" )
3996 main.log.debug( self.name + " expected: " + pattern )
3997 main.log.debug( self.name + " actual: " + repr( output ) )
3998 match = None
3999 if match:
4000 setMatch = match.group( 1 )
4001 if setMatch == '':
4002 setList = []
4003 else:
4004 setList = setMatch.split( ", " )
4005 if length > 0:
4006 return ( setList, containsCheck )
4007 else:
4008 return setList
4009 else: # no match
4010 main.log.error( self.name + ": setTestGet did not" +
4011 " match expected output" )
4012 main.log.debug( self.name + " expected: " + pattern )
4013 main.log.debug( self.name + " actual: " + repr( output ) )
4014 return main.ERROR
4015 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004016 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004017 return main.ERROR
4018 except TypeError:
4019 main.log.exception( self.name + ": Object not as expected" )
4020 return main.ERROR
4021 except pexpect.EOF:
4022 main.log.error( self.name + ": EOF exception found" )
4023 main.log.error( self.name + ": " + self.handle.before )
4024 main.cleanup()
4025 main.exit()
4026 except Exception:
4027 main.log.exception( self.name + ": Uncaught exception!" )
4028 main.cleanup()
4029 main.exit()
4030
4031 def setTestSize( self, setName ):
4032 """
4033 CLI command to get the elements in a distributed set.
4034 Required arguments:
4035 setName - The name of the set to remove from.
4036 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004037 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004038 None on error
4039 """
4040 try:
4041 # TODO: Should this check against the number of elements returned
4042 # and then return true/false based on that?
4043 setName = str( setName ).strip()
4044 # Patterns to match
4045 setPattern = "\[(.*)\]"
4046 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4047 setPattern
4048 cmdStr = "set-test-get -s "
4049 cmdStr += setName
4050 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004051 try:
4052 # TODO: Maybe make this less hardcoded
4053 # ConsistentMap Exceptions
4054 assert "org.onosproject.store.service" not in output
4055 # Node not leader
4056 assert "java.lang.IllegalStateException" not in output
4057 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004058 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004059 "command: " + str( output ) )
4060 retryTime = 30 # Conservative time, given by Madan
4061 main.log.info( "Waiting " + str( retryTime ) +
4062 "seconds before retrying." )
4063 time.sleep( retryTime ) # Due to change in mastership
4064 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004065 assert "Command not found:" not in output, output
4066 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004067 main.log.info( self.name + ": " + output )
4068 match = re.search( pattern, output )
4069 if match:
4070 setSize = int( match.group( 1 ) )
4071 setMatch = match.group( 2 )
4072 if len( setMatch.split() ) == setSize:
4073 main.log.info( "The size returned by " + self.name +
4074 " matches the number of elements in " +
4075 "the returned set" )
4076 else:
4077 main.log.error( "The size returned by " + self.name +
4078 " does not match the number of " +
4079 "elements in the returned set." )
4080 return setSize
4081 else: # no match
4082 main.log.error( self.name + ": setTestGet did not" +
4083 " match expected output" )
4084 main.log.debug( self.name + " expected: " + pattern )
4085 main.log.debug( self.name + " actual: " + repr( output ) )
4086 return None
4087 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004088 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004089 return None
Jon Hall390696c2015-05-05 17:13:41 -07004090 except TypeError:
4091 main.log.exception( self.name + ": Object not as expected" )
4092 return None
4093 except pexpect.EOF:
4094 main.log.error( self.name + ": EOF exception found" )
4095 main.log.error( self.name + ": " + self.handle.before )
4096 main.cleanup()
4097 main.exit()
4098 except Exception:
4099 main.log.exception( self.name + ": Uncaught exception!" )
4100 main.cleanup()
4101 main.exit()
4102
Jon Hall80daded2015-05-27 16:07:00 -07004103 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004104 """
4105 Command to list the various counters in the system.
4106 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004107 if jsonFormat, a string of the json object returned by the cli
4108 command
4109 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004110 None on error
4111 """
Jon Hall390696c2015-05-05 17:13:41 -07004112 try:
4113 counters = {}
4114 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004115 if jsonFormat:
4116 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004117 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004118 assert "Command not found:" not in output, output
4119 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004120 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004121 return output
Jon Hall390696c2015-05-05 17:13:41 -07004122 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004123 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004124 return None
Jon Hall390696c2015-05-05 17:13:41 -07004125 except TypeError:
4126 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004127 return None
Jon Hall390696c2015-05-05 17:13:41 -07004128 except pexpect.EOF:
4129 main.log.error( self.name + ": EOF exception found" )
4130 main.log.error( self.name + ": " + self.handle.before )
4131 main.cleanup()
4132 main.exit()
4133 except Exception:
4134 main.log.exception( self.name + ": Uncaught exception!" )
4135 main.cleanup()
4136 main.exit()
4137
Jon Hall935db192016-04-19 00:22:04 -07004138 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004139 """
Jon Halle1a3b752015-07-22 13:02:46 -07004140 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004141 Required arguments:
4142 counter - The name of the counter to increment.
4143 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004144 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004145 returns:
4146 integer value of the counter or
4147 None on Error
4148 """
4149 try:
4150 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004151 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004152 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004153 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004154 if delta != 1:
4155 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004156 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004157 try:
4158 # TODO: Maybe make this less hardcoded
4159 # ConsistentMap Exceptions
4160 assert "org.onosproject.store.service" not in output
4161 # Node not leader
4162 assert "java.lang.IllegalStateException" not in output
4163 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004164 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004165 "command: " + str( output ) )
4166 retryTime = 30 # Conservative time, given by Madan
4167 main.log.info( "Waiting " + str( retryTime ) +
4168 "seconds before retrying." )
4169 time.sleep( retryTime ) # Due to change in mastership
4170 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004171 assert "Command not found:" not in output, output
4172 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004173 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004174 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004175 match = re.search( pattern, output )
4176 if match:
4177 return int( match.group( 1 ) )
4178 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004179 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004180 " match expected output." )
4181 main.log.debug( self.name + " expected: " + pattern )
4182 main.log.debug( self.name + " actual: " + repr( output ) )
4183 return None
4184 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004185 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004186 return None
4187 except TypeError:
4188 main.log.exception( self.name + ": Object not as expected" )
4189 return None
4190 except pexpect.EOF:
4191 main.log.error( self.name + ": EOF exception found" )
4192 main.log.error( self.name + ": " + self.handle.before )
4193 main.cleanup()
4194 main.exit()
4195 except Exception:
4196 main.log.exception( self.name + ": Uncaught exception!" )
4197 main.cleanup()
4198 main.exit()
4199
Jon Hall935db192016-04-19 00:22:04 -07004200 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004201 """
4202 CLI command to get a distributed counter then add a delta to it.
4203 Required arguments:
4204 counter - The name of the counter to increment.
4205 Optional arguments:
4206 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004207 returns:
4208 integer value of the counter or
4209 None on Error
4210 """
4211 try:
4212 counter = str( counter )
4213 delta = int( delta )
4214 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004215 cmdStr += counter
4216 if delta != 1:
4217 cmdStr += " " + str( delta )
4218 output = self.sendline( cmdStr )
4219 try:
4220 # TODO: Maybe make this less hardcoded
4221 # ConsistentMap Exceptions
4222 assert "org.onosproject.store.service" not in output
4223 # Node not leader
4224 assert "java.lang.IllegalStateException" not in output
4225 except AssertionError:
4226 main.log.error( "Error in processing '" + cmdStr + "' " +
4227 "command: " + str( output ) )
4228 retryTime = 30 # Conservative time, given by Madan
4229 main.log.info( "Waiting " + str( retryTime ) +
4230 "seconds before retrying." )
4231 time.sleep( retryTime ) # Due to change in mastership
4232 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004233 assert "Command not found:" not in output, output
4234 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004235 main.log.info( self.name + ": " + output )
4236 pattern = counter + " was updated to (-?\d+)"
4237 match = re.search( pattern, output )
4238 if match:
4239 return int( match.group( 1 ) )
4240 else:
4241 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4242 " match expected output." )
4243 main.log.debug( self.name + " expected: " + pattern )
4244 main.log.debug( self.name + " actual: " + repr( output ) )
4245 return None
4246 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004247 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004248 return None
4249 except TypeError:
4250 main.log.exception( self.name + ": Object not as expected" )
4251 return None
4252 except pexpect.EOF:
4253 main.log.error( self.name + ": EOF exception found" )
4254 main.log.error( self.name + ": " + self.handle.before )
4255 main.cleanup()
4256 main.exit()
4257 except Exception:
4258 main.log.exception( self.name + ": Uncaught exception!" )
4259 main.cleanup()
4260 main.exit()
4261
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004262 def summary( self, jsonFormat=True ):
4263 """
4264 Description: Execute summary command in onos
4265 Returns: json object ( summary -j ), returns main.FALSE if there is
4266 no output
4267
4268 """
4269 try:
4270 cmdStr = "summary"
4271 if jsonFormat:
4272 cmdStr += " -j"
4273 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004274 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004275 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004276 if not handle:
4277 main.log.error( self.name + ": There is no output in " +
4278 "summary command" )
4279 return main.FALSE
4280 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004281 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004282 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004283 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004284 except TypeError:
4285 main.log.exception( self.name + ": Object not as expected" )
4286 return None
4287 except pexpect.EOF:
4288 main.log.error( self.name + ": EOF exception found" )
4289 main.log.error( self.name + ": " + self.handle.before )
4290 main.cleanup()
4291 main.exit()
4292 except Exception:
4293 main.log.exception( self.name + ": Uncaught exception!" )
4294 main.cleanup()
4295 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004296
Jon Hall935db192016-04-19 00:22:04 -07004297 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004298 """
4299 CLI command to get the value of a key in a consistent map using
4300 transactions. This a test function and can only get keys from the
4301 test map hard coded into the cli command
4302 Required arguments:
4303 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004304 returns:
4305 The string value of the key or
4306 None on Error
4307 """
4308 try:
4309 keyName = str( keyName )
4310 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004311 cmdStr += keyName
4312 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004313 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004314 try:
4315 # TODO: Maybe make this less hardcoded
4316 # ConsistentMap Exceptions
4317 assert "org.onosproject.store.service" not in output
4318 # Node not leader
4319 assert "java.lang.IllegalStateException" not in output
4320 except AssertionError:
4321 main.log.error( "Error in processing '" + cmdStr + "' " +
4322 "command: " + str( output ) )
4323 return None
4324 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4325 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004326 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004327 return None
4328 else:
4329 match = re.search( pattern, output )
4330 if match:
4331 return match.groupdict()[ 'value' ]
4332 else:
4333 main.log.error( self.name + ": transactionlMapGet did not" +
4334 " match expected output." )
4335 main.log.debug( self.name + " expected: " + pattern )
4336 main.log.debug( self.name + " actual: " + repr( output ) )
4337 return None
Jon Hallc6793552016-01-19 14:18:37 -08004338 except AssertionError:
4339 main.log.exception( "" )
4340 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004341 except TypeError:
4342 main.log.exception( self.name + ": Object not as expected" )
4343 return None
4344 except pexpect.EOF:
4345 main.log.error( self.name + ": EOF exception found" )
4346 main.log.error( self.name + ": " + self.handle.before )
4347 main.cleanup()
4348 main.exit()
4349 except Exception:
4350 main.log.exception( self.name + ": Uncaught exception!" )
4351 main.cleanup()
4352 main.exit()
4353
Jon Hall935db192016-04-19 00:22:04 -07004354 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004355 """
4356 CLI command to put a value into 'numKeys' number of keys in a
4357 consistent map using transactions. This a test function and can only
4358 put into keys named 'Key#' of the test map hard coded into the cli command
4359 Required arguments:
4360 numKeys - Number of keys to add the value to
4361 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004362 returns:
4363 A dictionary whose keys are the name of the keys put into the map
4364 and the values of the keys are dictionaries whose key-values are
4365 'value': value put into map and optionaly
4366 'oldValue': Previous value in the key or
4367 None on Error
4368
4369 Example output
4370 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4371 'Key2': {'value': 'Testing'} }
4372 """
4373 try:
4374 numKeys = str( numKeys )
4375 value = str( value )
4376 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004377 cmdStr += numKeys + " " + value
4378 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004379 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004380 try:
4381 # TODO: Maybe make this less hardcoded
4382 # ConsistentMap Exceptions
4383 assert "org.onosproject.store.service" not in output
4384 # Node not leader
4385 assert "java.lang.IllegalStateException" not in output
4386 except AssertionError:
4387 main.log.error( "Error in processing '" + cmdStr + "' " +
4388 "command: " + str( output ) )
4389 return None
4390 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4391 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4392 results = {}
4393 for line in output.splitlines():
4394 new = re.search( newPattern, line )
4395 updated = re.search( updatedPattern, line )
4396 if new:
4397 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4398 elif updated:
4399 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004400 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004401 else:
4402 main.log.error( self.name + ": transactionlMapGet did not" +
4403 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004404 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4405 newPattern,
4406 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004407 main.log.debug( self.name + " actual: " + repr( output ) )
4408 return results
Jon Hallc6793552016-01-19 14:18:37 -08004409 except AssertionError:
4410 main.log.exception( "" )
4411 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004412 except TypeError:
4413 main.log.exception( self.name + ": Object not as expected" )
4414 return None
4415 except pexpect.EOF:
4416 main.log.error( self.name + ": EOF exception found" )
4417 main.log.error( self.name + ": " + self.handle.before )
4418 main.cleanup()
4419 main.exit()
4420 except Exception:
4421 main.log.exception( self.name + ": Uncaught exception!" )
4422 main.cleanup()
4423 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004424
acsmarsdaea66c2015-09-03 11:44:06 -07004425 def maps( self, jsonFormat=True ):
4426 """
4427 Description: Returns result of onos:maps
4428 Optional:
4429 * jsonFormat: enable json formatting of output
4430 """
4431 try:
4432 cmdStr = "maps"
4433 if jsonFormat:
4434 cmdStr += " -j"
4435 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004436 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004437 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004438 except AssertionError:
4439 main.log.exception( "" )
4440 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return None
4444 except pexpect.EOF:
4445 main.log.error( self.name + ": EOF exception found" )
4446 main.log.error( self.name + ": " + self.handle.before )
4447 main.cleanup()
4448 main.exit()
4449 except Exception:
4450 main.log.exception( self.name + ": Uncaught exception!" )
4451 main.cleanup()
4452 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004453
4454 def getSwController( self, uri, jsonFormat=True ):
4455 """
4456 Descrition: Gets the controller information from the device
4457 """
4458 try:
4459 cmd = "device-controllers "
4460 if jsonFormat:
4461 cmd += "-j "
4462 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004463 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004464 return response
Jon Hallc6793552016-01-19 14:18:37 -08004465 except AssertionError:
4466 main.log.exception( "" )
4467 return None
GlennRC050596c2015-11-18 17:06:41 -08004468 except TypeError:
4469 main.log.exception( self.name + ": Object not as expected" )
4470 return None
4471 except pexpect.EOF:
4472 main.log.error( self.name + ": EOF exception found" )
4473 main.log.error( self.name + ": " + self.handle.before )
4474 main.cleanup()
4475 main.exit()
4476 except Exception:
4477 main.log.exception( self.name + ": Uncaught exception!" )
4478 main.cleanup()
4479 main.exit()
4480
4481 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4482 """
4483 Descrition: sets the controller(s) for the specified device
4484
4485 Parameters:
4486 Required: uri - String: The uri of the device(switch).
4487 ip - String or List: The ip address of the controller.
4488 This parameter can be formed in a couple of different ways.
4489 VALID:
4490 10.0.0.1 - just the ip address
4491 tcp:10.0.0.1 - the protocol and the ip address
4492 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4493 so that you can add controllers with different
4494 protocols and ports
4495 INVALID:
4496 10.0.0.1:6653 - this is not supported by ONOS
4497
4498 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4499 port - The port number.
4500 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4501
4502 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4503 """
4504 try:
4505 cmd = "device-setcontrollers"
4506
4507 if jsonFormat:
4508 cmd += " -j"
4509 cmd += " " + uri
4510 if isinstance( ip, str ):
4511 ip = [ip]
4512 for item in ip:
4513 if ":" in item:
4514 sitem = item.split( ":" )
4515 if len(sitem) == 3:
4516 cmd += " " + item
4517 elif "." in sitem[1]:
4518 cmd += " {}:{}".format(item, port)
4519 else:
4520 main.log.error( "Malformed entry: " + item )
4521 raise TypeError
4522 else:
4523 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004524 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004525 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004526 if "Error" in response:
4527 main.log.error( response )
4528 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004529 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004530 except AssertionError:
4531 main.log.exception( "" )
4532 return None
GlennRC050596c2015-11-18 17:06:41 -08004533 except TypeError:
4534 main.log.exception( self.name + ": Object not as expected" )
4535 return main.FALSE
4536 except pexpect.EOF:
4537 main.log.error( self.name + ": EOF exception found" )
4538 main.log.error( self.name + ": " + self.handle.before )
4539 main.cleanup()
4540 main.exit()
4541 except Exception:
4542 main.log.exception( self.name + ": Uncaught exception!" )
4543 main.cleanup()
4544 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004545
4546 def removeDevice( self, device ):
4547 '''
4548 Description:
4549 Remove a device from ONOS by passing the uri of the device(s).
4550 Parameters:
4551 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4552 Returns:
4553 Returns main.FALSE if an exception is thrown or an error is present
4554 in the response. Otherwise, returns main.TRUE.
4555 NOTE:
4556 If a host cannot be removed, then this function will return main.FALSE
4557 '''
4558 try:
4559 if type( device ) is str:
4560 device = list( device )
4561
4562 for d in device:
4563 time.sleep( 1 )
4564 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004565 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004566 if "Error" in response:
4567 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4568 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004569 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004570 except AssertionError:
4571 main.log.exception( "" )
4572 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004573 except TypeError:
4574 main.log.exception( self.name + ": Object not as expected" )
4575 return main.FALSE
4576 except pexpect.EOF:
4577 main.log.error( self.name + ": EOF exception found" )
4578 main.log.error( self.name + ": " + self.handle.before )
4579 main.cleanup()
4580 main.exit()
4581 except Exception:
4582 main.log.exception( self.name + ": Uncaught exception!" )
4583 main.cleanup()
4584 main.exit()
4585
4586 def removeHost( self, host ):
4587 '''
4588 Description:
4589 Remove a host from ONOS by passing the id of the host(s)
4590 Parameters:
4591 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4592 Returns:
4593 Returns main.FALSE if an exception is thrown or an error is present
4594 in the response. Otherwise, returns main.TRUE.
4595 NOTE:
4596 If a host cannot be removed, then this function will return main.FALSE
4597 '''
4598 try:
4599 if type( host ) is str:
4600 host = list( host )
4601
4602 for h in host:
4603 time.sleep( 1 )
4604 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004605 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004606 if "Error" in response:
4607 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4608 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004609 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004610 except AssertionError:
4611 main.log.exception( "" )
4612 return None
GlennRC20fc6522015-12-23 23:26:57 -08004613 except TypeError:
4614 main.log.exception( self.name + ": Object not as expected" )
4615 return main.FALSE
4616 except pexpect.EOF:
4617 main.log.error( self.name + ": EOF exception found" )
4618 main.log.error( self.name + ": " + self.handle.before )
4619 main.cleanup()
4620 main.exit()
4621 except Exception:
4622 main.log.exception( self.name + ": Uncaught exception!" )
4623 main.cleanup()
4624 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004625
Jon Hallc6793552016-01-19 14:18:37 -08004626 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004627 '''
4628 Description:
4629 Bring link down or up in the null-provider.
4630 params:
4631 begin - (string) One end of a device or switch.
4632 end - (string) the other end of the device or switch
4633 returns:
4634 main.TRUE if no exceptions were thrown and no Errors are
4635 present in the resoponse. Otherwise, returns main.FALSE
4636 '''
4637 try:
Jon Hallc6793552016-01-19 14:18:37 -08004638 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004639 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004640 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004641 if "Error" in response or "Failure" in response:
4642 main.log.error( response )
4643 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004644 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004645 except AssertionError:
4646 main.log.exception( "" )
4647 return None
GlennRCed771242016-01-13 17:02:47 -08004648 except TypeError:
4649 main.log.exception( self.name + ": Object not as expected" )
4650 return main.FALSE
4651 except pexpect.EOF:
4652 main.log.error( self.name + ": EOF exception found" )
4653 main.log.error( self.name + ": " + self.handle.before )
4654 main.cleanup()
4655 main.exit()
4656 except Exception:
4657 main.log.exception( self.name + ": Uncaught exception!" )
4658 main.cleanup()
4659 main.exit()
4660