blob: 9fcf42d2421ce41fca88568d3a221d1d82f54c36 [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
Jon Hallefbd9792015-03-05 16:11:36 -0800304 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800305 """
306 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800307 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800308 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800309 Available level: DEBUG, TRACE, INFO, WARN, ERROR
310 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800311 """
312 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800313 lvlStr = ""
314 if level:
315 lvlStr = "--level=" + level
316
kelvin-onlab9f541032015-02-04 16:19:53 -0800317 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800318 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700319 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800320 main.log.error( self.name + ": onos cli session closed. ")
321 if self.onosIp:
322 main.log.warn( "Trying to reconnect " + self.onosIp )
323 reconnectResult = self.startOnosCli( self.onosIp )
324 if reconnectResult:
325 main.log.info( self.name + ": onos cli session reconnected." )
326 else:
327 main.log.error( self.name + ": reconnection failed." )
328 main.cleanup()
329 main.exit()
330 else:
331 main.cleanup()
332 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700333 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700334 self.handle.sendline( "" )
335 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800336 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700337 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800338 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800339
kelvin-onlab9f541032015-02-04 16:19:53 -0800340 response = self.handle.before
341 if re.search( "Error", response ):
342 return main.FALSE
343 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700344 except pexpect.TIMEOUT:
345 main.log.exception( self.name + ": TIMEOUT exception found" )
346 main.cleanup()
347 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800348 except pexpect.EOF:
349 main.log.error( self.name + ": EOF exception found" )
350 main.log.error( self.name + ": " + self.handle.before )
351 main.cleanup()
352 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800353 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800354 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400355 main.cleanup()
356 main.exit()
357
GlennRCed771242016-01-13 17:02:47 -0800358 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800359 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800360 Send a completely user specified string to
361 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400362 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800363
andrewonlaba18f6bf2014-10-13 19:31:54 -0400364 Warning: There are no sanity checking to commands
365 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800366
kelvin8ec71442015-01-15 16:57:00 -0800367 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400368 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800369 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
370 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800372 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800373 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800374 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800375 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
376 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700377 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700378 main.log.debug( self.name + ": Raw output" )
379 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700380
381 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800382 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800383 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700384 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700385 main.log.debug( self.name + ": ansiEscape output" )
386 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700387
kelvin-onlabfb521662015-02-27 09:52:40 -0800388 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800389 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700390 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700391 main.log.debug( self.name + ": Removed extra returns " +
392 "from output" )
393 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700394
395 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800396 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700397 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700398 main.log.debug( self.name + ": parsed and stripped output" )
399 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700400
Jon Hall63604932015-02-26 17:09:50 -0800401 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700402 output = response.split( cmdStr.strip(), 1 )
403 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700404 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700405 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700406 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800407 output = output[1].strip()
408 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800409 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800410 return output
GlennRCed771242016-01-13 17:02:47 -0800411 except pexpect.TIMEOUT:
412 main.log.error( self.name + ":ONOS timeout" )
413 if debug:
414 main.log.debug( self.handle.before )
415 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700416 except IndexError:
417 main.log.exception( self.name + ": Object not as expected" )
418 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800419 except TypeError:
420 main.log.exception( self.name + ": Object not as expected" )
421 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400422 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800423 main.log.error( self.name + ": EOF exception found" )
424 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400425 main.cleanup()
426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800427 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800428 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400429 main.cleanup()
430 main.exit()
431
kelvin8ec71442015-01-15 16:57:00 -0800432 # IMPORTANT NOTE:
433 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800434 # the cli command changing 'a:b' with 'aB'.
435 # Ex ) onos:topology > onosTopology
436 # onos:links > onosLinks
437 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800438
kelvin-onlabd3b64892015-01-20 13:26:24 -0800439 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800440 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 Adds a new cluster node by ID and address information.
442 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800443 * nodeId
444 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800446 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400448 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800449 cmdStr = "add-node " + str( nodeId ) + " " +\
450 str( ONOSIp ) + " " + str( tcpPort )
451 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800452 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800453 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( "Error in adding node" )
455 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800456 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800458 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400459 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800460 except AssertionError:
461 main.log.exception( "" )
462 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800463 except TypeError:
464 main.log.exception( self.name + ": Object not as expected" )
465 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400466 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400469 main.cleanup()
470 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800472 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400473 main.cleanup()
474 main.exit()
475
kelvin-onlabd3b64892015-01-20 13:26:24 -0800476 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800477 """
andrewonlab86dc3082014-10-13 18:18:38 -0400478 Removes a cluster by ID
479 Issues command: 'remove-node [<node-id>]'
480 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800482 """
andrewonlab86dc3082014-10-13 18:18:38 -0400483 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400484
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700486 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800487 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 if re.search( "Error", handle ):
489 main.log.error( "Error in removing node" )
490 main.log.error( handle )
491 return main.FALSE
492 else:
493 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800494 except AssertionError:
495 main.log.exception( "" )
496 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800497 except TypeError:
498 main.log.exception( self.name + ": Object not as expected" )
499 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400500 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800501 main.log.error( self.name + ": EOF exception found" )
502 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400503 main.cleanup()
504 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800505 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800506 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400507 main.cleanup()
508 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400509
Jon Hall61282e32015-03-19 11:34:11 -0700510 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800511 """
andrewonlab7c211572014-10-15 16:45:20 -0400512 List the nodes currently visible
513 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700514 Optional argument:
515 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800516 """
andrewonlab7c211572014-10-15 16:45:20 -0400517 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700519 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700520 cmdStr += " -j"
521 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800522 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 return output
Jon Hallc6793552016-01-19 14:18:37 -0800524 except AssertionError:
525 main.log.exception( "" )
526 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800527 except TypeError:
528 main.log.exception( self.name + ": Object not as expected" )
529 return None
andrewonlab7c211572014-10-15 16:45:20 -0400530 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800531 main.log.error( self.name + ": EOF exception found" )
532 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400537 main.cleanup()
538 main.exit()
539
kelvin8ec71442015-01-15 16:57:00 -0800540 def topology( self ):
541 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700542 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700543 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700544 Return:
545 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800546 """
andrewonlab95ce8322014-10-13 14:12:04 -0400547 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700548 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800549 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800550 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700551 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400552 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800553 except AssertionError:
554 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800555 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800556 except TypeError:
557 main.log.exception( self.name + ": Object not as expected" )
558 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400562 main.cleanup()
563 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800564 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800565 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 main.cleanup()
567 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800568
jenkins7ead5a82015-03-13 10:28:21 -0700569 def deviceRemove( self, deviceId ):
570 """
571 Removes particular device from storage
572
573 TODO: refactor this function
574 """
575 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 cmdStr = "device-remove " + str( deviceId )
577 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800578 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700579 if re.search( "Error", handle ):
580 main.log.error( "Error in removing device" )
581 main.log.error( handle )
582 return main.FALSE
583 else:
584 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800585 except AssertionError:
586 main.log.exception( "" )
587 return None
jenkins7ead5a82015-03-13 10:28:21 -0700588 except TypeError:
589 main.log.exception( self.name + ": Object not as expected" )
590 return None
591 except pexpect.EOF:
592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
594 main.cleanup()
595 main.exit()
596 except Exception:
597 main.log.exception( self.name + ": Uncaught exception!" )
598 main.cleanup()
599 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700600
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800602 """
Jon Hall7b02d952014-10-17 20:14:54 -0400603 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400604 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800606 """
andrewonlab86dc3082014-10-13 18:18:38 -0400607 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700608 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800609 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700610 cmdStr += " -j"
611 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800612 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700613 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800614 except AssertionError:
615 main.log.exception( "" )
616 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800617 except TypeError:
618 main.log.exception( self.name + ": Object not as expected" )
619 return None
andrewonlab7c211572014-10-15 16:45:20 -0400620 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800621 main.log.error( self.name + ": EOF exception found" )
622 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400623 main.cleanup()
624 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800625 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800626 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400627 main.cleanup()
628 main.exit()
629
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800631 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800632 This balances the devices across all controllers
633 by issuing command: 'onos> onos:balance-masters'
634 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800635 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800636 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800639 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700640 if re.search( "Error", handle ):
641 main.log.error( "Error in balancing masters" )
642 main.log.error( handle )
643 return main.FALSE
644 else:
645 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800646 except AssertionError:
647 main.log.exception( "" )
648 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800649 except TypeError:
650 main.log.exception( self.name + ": Object not as expected" )
651 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800652 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800653 main.log.error( self.name + ": EOF exception found" )
654 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800655 main.cleanup()
656 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800658 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800659 main.cleanup()
660 main.exit()
661
Jon Hallc6793552016-01-19 14:18:37 -0800662 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700663 """
664 Returns the output of the masters command.
665 Optional argument:
666 * jsonFormat - boolean indicating if you want output in json
667 """
668 try:
669 cmdStr = "onos:masters"
670 if jsonFormat:
671 cmdStr += " -j"
672 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800673 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700674 return output
Jon Hallc6793552016-01-19 14:18:37 -0800675 except AssertionError:
676 main.log.exception( "" )
677 return None
acsmars24950022015-07-30 18:00:43 -0700678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
681 except pexpect.EOF:
682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
684 main.cleanup()
685 main.exit()
686 except Exception:
687 main.log.exception( self.name + ": Uncaught exception!" )
688 main.cleanup()
689 main.exit()
690
Jon Hallc6793552016-01-19 14:18:37 -0800691 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700692 """
693 Uses the master command to check that the devices' leadership
694 is evenly divided
695
696 Dependencies: checkMasters() and summary()
697
698 Returns main.True if the devices are balanced
699 Returns main.False if the devices are unbalanced
700 Exits on Exception
701 Returns None on TypeError
702 """
703 try:
Jon Hallc6793552016-01-19 14:18:37 -0800704 summaryOutput = self.summary()
705 totalDevices = json.loads( summaryOutput )[ "devices" ]
706 except ( TypeError, ValueError ):
707 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
708 return None
709 try:
acsmars24950022015-07-30 18:00:43 -0700710 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800711 mastersOutput = self.checkMasters()
712 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700713 first = masters[ 0 ][ "size" ]
714 for master in masters:
715 totalOwnedDevices += master[ "size" ]
716 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
717 main.log.error( "Mastership not balanced" )
718 main.log.info( "\n" + self.checkMasters( False ) )
719 return main.FALSE
720 main.log.info( "Mastership balanced between " \
721 + str( len(masters) ) + " masters" )
722 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800723 except ( TypeError, ValueError ):
724 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700725 return None
726 except pexpect.EOF:
727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
729 main.cleanup()
730 main.exit()
731 except Exception:
732 main.log.exception( self.name + ": Uncaught exception!" )
733 main.cleanup()
734 main.exit()
735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800737 """
Jon Halle8217482014-10-17 13:49:14 -0400738 Lists all core links
739 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Jon Halle8217482014-10-17 13:49:14 -0400742 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700743 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 cmdStr += " -j"
746 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800747 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800749 except AssertionError:
750 main.log.exception( "" )
751 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800752 except TypeError:
753 main.log.exception( self.name + ": Object not as expected" )
754 return None
Jon Halle8217482014-10-17 13:49:14 -0400755 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800756 main.log.error( self.name + ": EOF exception found" )
757 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400758 main.cleanup()
759 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800761 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400762 main.cleanup()
763 main.exit()
764
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800766 """
Jon Halle8217482014-10-17 13:49:14 -0400767 Lists all ports
768 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800770 """
Jon Halle8217482014-10-17 13:49:14 -0400771 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 cmdStr += " -j"
775 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800776 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800778 except AssertionError:
779 main.log.exception( "" )
780 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800781 except TypeError:
782 main.log.exception( self.name + ": Object not as expected" )
783 return None
Jon Halle8217482014-10-17 13:49:14 -0400784 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400787 main.cleanup()
788 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800789 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800790 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400791 main.cleanup()
792 main.exit()
793
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800795 """
Jon Hall983a1702014-10-28 18:44:22 -0400796 Lists all devices and the controllers with roles assigned to them
797 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800799 """
andrewonlab7c211572014-10-15 16:45:20 -0400800 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700801 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700803 cmdStr += " -j"
804 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800805 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800807 except AssertionError:
808 main.log.exception( "" )
809 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800810 except TypeError:
811 main.log.exception( self.name + ": Object not as expected" )
812 return None
Jon Hall983a1702014-10-28 18:44:22 -0400813 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400816 main.cleanup()
817 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800818 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800819 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400820 main.cleanup()
821 main.exit()
822
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800824 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800825 Given the a string containing the json representation of the "roles"
826 cli command and a partial or whole device id, returns a json object
827 containing the roles output for the first device whose id contains
828 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400829
830 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800831 A dict of the role assignments for the given device or
832 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800833 """
Jon Hall983a1702014-10-28 18:44:22 -0400834 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800835 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400836 return None
837 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800838 rawRoles = self.roles()
839 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800840 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800842 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800843 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400844 return device
845 return None
Jon Hallc6793552016-01-19 14:18:37 -0800846 except ( TypeError, ValueError ):
847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800848 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400852 main.cleanup()
853 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800855 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400856 main.cleanup()
857 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800858
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Hall94fd0472014-12-08 11:52:42 -0800861 Iterates through each device and checks if there is a master assigned
862 Returns: main.TRUE if each device has a master
863 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800864 """
Jon Hall94fd0472014-12-08 11:52:42 -0800865 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800866 rawRoles = self.roles()
867 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800868 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800870 # print device
871 if device[ 'master' ] == "none":
872 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800873 return main.FALSE
874 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800875 except ( TypeError, ValueError ):
876 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800877 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400890 Returns string of paths, and the cost.
891 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800892 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
895 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800896 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800897 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( "Error in getting paths" )
899 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400900 else:
kelvin8ec71442015-01-15 16:57:00 -0800901 path = handle.split( ";" )[ 0 ]
902 cost = handle.split( ";" )[ 1 ]
903 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800904 except AssertionError:
905 main.log.exception( "" )
906 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800907 except TypeError:
908 main.log.exception( self.name + ": Object not as expected" )
909 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400913 main.cleanup()
914 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800915 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800916 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400917 main.cleanup()
918 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800919
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800921 """
Jon Hallffb386d2014-11-21 13:43:38 -0800922 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400923 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400926 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700927 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 cmdStr += " -j"
930 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -0700931 if handle:
932 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800933 # TODO: Maybe make this less hardcoded
934 # ConsistentMap Exceptions
935 assert "org.onosproject.store.service" not in handle
936 # Node not leader
937 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -0700940 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -0700941 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -0800942 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800943 except TypeError:
944 main.log.exception( self.name + ": Object not as expected" )
945 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400946 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800947 main.log.error( self.name + ": EOF exception found" )
948 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400949 main.cleanup()
950 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800951 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800952 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 main.cleanup()
954 main.exit()
955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800957 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400958 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800959
Jon Hallefbd9792015-03-05 16:11:36 -0800960 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 partial mac address
962
Jon Hall42db6dc2014-10-24 19:03:48 -0400963 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800964 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400965 try:
kelvin8ec71442015-01-15 16:57:00 -0800966 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400967 return None
968 else:
969 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 rawHosts = self.hosts()
971 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800972 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800974 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800975 if not host:
976 pass
977 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400978 return host
979 return None
Jon Hallc6793552016-01-19 14:18:37 -0800980 except ( TypeError, ValueError ):
981 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800982 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400986 main.cleanup()
987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800989 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400990 main.cleanup()
991 main.exit()
992
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800994 """
995 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400996 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800997
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000 IMPORTANT:
1001 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001002 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003 Furthermore, it assumes that value of VLAN is '-1'
1004 Description:
kelvin8ec71442015-01-15 16:57:00 -08001005 Converts mininet hosts ( h1, h2, h3... ) into
1006 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1007 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001008 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001010
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001012 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 hostHex = hex( int( host ) ).zfill( 12 )
1014 hostHex = str( hostHex ).replace( 'x', '0' )
1015 i = iter( str( hostHex ) )
1016 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1017 hostHex = hostHex + "/-1"
1018 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001019
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001021
Jon Halld4d4b372015-01-28 16:02:41 -08001022 except TypeError:
1023 main.log.exception( self.name + ": Object not as expected" )
1024 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001025 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001026 main.log.error( self.name + ": EOF exception found" )
1027 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001028 main.cleanup()
1029 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001031 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001032 main.cleanup()
1033 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001034
Jeremy Songster832f9e92016-05-05 14:30:49 -07001035 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001036 """
andrewonlabe6745342014-10-17 14:29:13 -04001037 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 * hostIdOne: ONOS host id for host1
1039 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001040 Optional:
1041 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001042 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001043 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001044 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001045 Returns:
1046 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001047 """
andrewonlabe6745342014-10-17 14:29:13 -04001048 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001049 cmdStr = "add-host-intent "
1050 if vlanId:
1051 cmdStr += "-v " + str( vlanId ) + " "
1052 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001054 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001055 if re.search( "Error", handle ):
1056 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001057 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001058 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001059 else:
1060 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001061 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1062 match = re.search('id=0x([\da-f]+),', handle)
1063 if match:
1064 return match.group()[3:-1]
1065 else:
1066 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001067 main.log.debug( "Response from ONOS was: " +
1068 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001069 return None
Jon Hallc6793552016-01-19 14:18:37 -08001070 except AssertionError:
1071 main.log.exception( "" )
1072 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001073 except TypeError:
1074 main.log.exception( self.name + ": Object not as expected" )
1075 return None
andrewonlabe6745342014-10-17 14:29:13 -04001076 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001077 main.log.error( self.name + ": EOF exception found" )
1078 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001079 main.cleanup()
1080 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001081 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001082 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001083 main.cleanup()
1084 main.exit()
1085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001087 """
andrewonlab7b31d232014-10-24 13:31:47 -04001088 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 * ingressDevice: device id of ingress device
1090 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001091 Optional:
1092 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001093 Description:
1094 Adds an optical intent by specifying an ingress and egress device
1095 Returns:
1096 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001097 """
andrewonlab7b31d232014-10-24 13:31:47 -04001098 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1100 " " + str( egressDevice )
1101 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001102 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001103 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001104 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001105 main.log.error( "Error in adding Optical intent" )
1106 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001107 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001108 main.log.info( "Optical intent installed between " +
1109 str( ingressDevice ) + " and " +
1110 str( egressDevice ) )
1111 match = re.search('id=0x([\da-f]+),', handle)
1112 if match:
1113 return match.group()[3:-1]
1114 else:
1115 main.log.error( "Error, intent ID not found" )
1116 return None
Jon Hallc6793552016-01-19 14:18:37 -08001117 except AssertionError:
1118 main.log.exception( "" )
1119 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001120 except TypeError:
1121 main.log.exception( self.name + ": Object not as expected" )
1122 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001126 main.cleanup()
1127 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001128 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001129 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001130 main.cleanup()
1131 main.exit()
1132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001134 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 ingressDevice,
1136 egressDevice,
1137 portIngress="",
1138 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001139 ethType="",
1140 ethSrc="",
1141 ethDst="",
1142 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001144 ipProto="",
1145 ipSrc="",
1146 ipDst="",
1147 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001148 tcpDst="",
1149 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001150 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001151 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001152 * ingressDevice: device id of ingress device
1153 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001154 Optional:
1155 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001156 * ethSrc: specify ethSrc ( i.e. src mac addr )
1157 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001158 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001160 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001161 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001162 * ipSrc: specify ip source address
1163 * ipDst: specify ip destination address
1164 * tcpSrc: specify tcp source port
1165 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001166 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001167 Description:
kelvin8ec71442015-01-15 16:57:00 -08001168 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001169 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001170 Returns:
1171 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001172
Jon Halle3f39ff2015-01-13 11:50:53 -08001173 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001174 options developers provide for point-to-point
1175 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001177 try:
kelvin8ec71442015-01-15 16:57:00 -08001178 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001179 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 and not ipProto and not ipSrc and not ipDst \
1182 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001183 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001184
andrewonlab289e4b72014-10-21 21:24:18 -04001185 else:
andrewonlab36af3822014-11-18 17:48:18 -05001186 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001187
andrewonlab0c0a6772014-10-22 12:31:18 -04001188 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001190 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001191 cmd += " --ethSrc " + str( ethSrc )
1192 if ethDst:
1193 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001194 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001195 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001197 cmd += " --lambda "
1198 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001199 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001200 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001201 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001202 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001203 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001204 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001206 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001207 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001208 if vlanId:
1209 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001210
kelvin8ec71442015-01-15 16:57:00 -08001211 # Check whether the user appended the port
1212 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 if "/" in ingressDevice:
1214 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001215 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001217 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001218 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001219 # Would it make sense to throw an exception and exit
1220 # the test?
1221 return None
andrewonlab36af3822014-11-18 17:48:18 -05001222
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 str( ingressDevice ) + "/" +\
1225 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001226
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 if "/" in egressDevice:
1228 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001229 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "You must specify the egress port" )
1232 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001233
kelvin8ec71442015-01-15 16:57:00 -08001234 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 str( egressDevice ) + "/" +\
1236 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001237
kelvin-onlab898a6c62015-01-16 14:13:53 -08001238 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001239 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001241 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001242 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001243 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001244 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001245 # TODO: print out all the options in this message?
1246 main.log.info( "Point-to-point intent installed between " +
1247 str( ingressDevice ) + " and " +
1248 str( egressDevice ) )
1249 match = re.search('id=0x([\da-f]+),', handle)
1250 if match:
1251 return match.group()[3:-1]
1252 else:
1253 main.log.error( "Error, intent ID not found" )
1254 return None
Jon Hallc6793552016-01-19 14:18:37 -08001255 except AssertionError:
1256 main.log.exception( "" )
1257 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001258 except TypeError:
1259 main.log.exception( self.name + ": Object not as expected" )
1260 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001261 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001262 main.log.error( self.name + ": EOF exception found" )
1263 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001264 main.cleanup()
1265 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001266 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001267 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001268 main.cleanup()
1269 main.exit()
1270
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 self,
shahshreyac2f97072015-03-19 17:04:29 -07001273 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001275 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001277 ethType="",
1278 ethSrc="",
1279 ethDst="",
1280 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001282 ipProto="",
1283 ipSrc="",
1284 ipDst="",
1285 tcpSrc="",
1286 tcpDst="",
1287 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001288 setEthDst="",
1289 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001290 """
shahshreyad0c80432014-12-04 16:56:05 -08001291 Note:
shahshreya70622b12015-03-19 17:19:00 -07001292 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001293 is same. That is, all ingress devices include port numbers
1294 with a "/" or all ingress devices could specify device
1295 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001296 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001297 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001298 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001300 Optional:
1301 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001302 * ethSrc: specify ethSrc ( i.e. src mac addr )
1303 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001304 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001305 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001306 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001307 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001308 * ipSrc: specify ip source address
1309 * ipDst: specify ip destination address
1310 * tcpSrc: specify tcp source port
1311 * tcpDst: specify tcp destination port
1312 * setEthSrc: action to Rewrite Source MAC Address
1313 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001314 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001315 Description:
kelvin8ec71442015-01-15 16:57:00 -08001316 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001317 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001318 Returns:
1319 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001320
Jon Halle3f39ff2015-01-13 11:50:53 -08001321 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001322 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001323 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001324 """
shahshreyad0c80432014-12-04 16:56:05 -08001325 try:
kelvin8ec71442015-01-15 16:57:00 -08001326 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001327 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001329 and not ipProto and not ipSrc and not ipDst\
1330 and not tcpSrc and not tcpDst and not setEthSrc\
1331 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001332 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001333
1334 else:
1335 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001336
shahshreyad0c80432014-12-04 16:56:05 -08001337 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001339 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " --ethSrc " + str( ethSrc )
1341 if ethDst:
1342 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001343 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001344 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001346 cmd += " --lambda "
1347 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001348 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001349 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001351 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001352 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001353 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001354 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001355 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001356 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001357 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001358 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001359 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001360 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001361 if vlanId:
1362 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001363
kelvin8ec71442015-01-15 16:57:00 -08001364 # Check whether the user appended the port
1365 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001366
1367 if portIngressList is None:
1368 for ingressDevice in ingressDeviceList:
1369 if "/" in ingressDevice:
1370 cmd += " " + str( ingressDevice )
1371 else:
1372 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001373 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001374 # TODO: perhaps more meaningful return
1375 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001376 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001377 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001378 for ingressDevice, portIngress in zip( ingressDeviceList,
1379 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001380 cmd += " " + \
1381 str( ingressDevice ) + "/" +\
1382 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001383 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001384 main.log.error( "Device list and port list does not " +
1385 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001386 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 if "/" in egressDevice:
1388 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001389 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001391 main.log.error( "You must specify " +
1392 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001393 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001394
kelvin8ec71442015-01-15 16:57:00 -08001395 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 str( egressDevice ) + "/" +\
1397 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001399 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001400 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001401 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001402 main.log.error( "Error in adding multipoint-to-singlepoint " +
1403 "intent" )
1404 return None
shahshreyad0c80432014-12-04 16:56:05 -08001405 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001406 match = re.search('id=0x([\da-f]+),', handle)
1407 if match:
1408 return match.group()[3:-1]
1409 else:
1410 main.log.error( "Error, intent ID not found" )
1411 return None
Jon Hallc6793552016-01-19 14:18:37 -08001412 except AssertionError:
1413 main.log.exception( "" )
1414 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001415 except TypeError:
1416 main.log.exception( self.name + ": Object not as expected" )
1417 return None
1418 except pexpect.EOF:
1419 main.log.error( self.name + ": EOF exception found" )
1420 main.log.error( self.name + ": " + self.handle.before )
1421 main.cleanup()
1422 main.exit()
1423 except Exception:
1424 main.log.exception( self.name + ": Uncaught exception!" )
1425 main.cleanup()
1426 main.exit()
1427
1428 def addSinglepointToMultipointIntent(
1429 self,
1430 ingressDevice,
1431 egressDeviceList,
1432 portIngress="",
1433 portEgressList=None,
1434 ethType="",
1435 ethSrc="",
1436 ethDst="",
1437 bandwidth="",
1438 lambdaAlloc=False,
1439 ipProto="",
1440 ipSrc="",
1441 ipDst="",
1442 tcpSrc="",
1443 tcpDst="",
1444 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001445 setEthDst="",
1446 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001447 """
1448 Note:
1449 This function assumes the format of all egress devices
1450 is same. That is, all egress devices include port numbers
1451 with a "/" or all egress devices could specify device
1452 ids and port numbers seperately.
1453 Required:
1454 * EgressDeviceList: List of device ids of egress device
1455 ( Atleast 2 eress devices required in the list )
1456 * ingressDevice: device id of ingress device
1457 Optional:
1458 * ethType: specify ethType
1459 * ethSrc: specify ethSrc ( i.e. src mac addr )
1460 * ethDst: specify ethDst ( i.e. dst mac addr )
1461 * bandwidth: specify bandwidth capacity of link
1462 * lambdaAlloc: if True, intent will allocate lambda
1463 for the specified intent
1464 * ipProto: specify ip protocol
1465 * ipSrc: specify ip source address
1466 * ipDst: specify ip destination address
1467 * tcpSrc: specify tcp source port
1468 * tcpDst: specify tcp destination port
1469 * setEthSrc: action to Rewrite Source MAC Address
1470 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001471 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001472 Description:
1473 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1474 specifying device id's and optional fields
1475 Returns:
1476 A string of the intent id or None on error
1477
1478 NOTE: This function may change depending on the
1479 options developers provide for singlepoint-to-multipoint
1480 intent via cli
1481 """
1482 try:
1483 # If there are no optional arguments
1484 if not ethType and not ethSrc and not ethDst\
1485 and not bandwidth and not lambdaAlloc\
1486 and not ipProto and not ipSrc and not ipDst\
1487 and not tcpSrc and not tcpDst and not setEthSrc\
1488 and not setEthDst:
1489 cmd = "add-single-to-multi-intent"
1490
1491 else:
1492 cmd = "add-single-to-multi-intent"
1493
1494 if ethType:
1495 cmd += " --ethType " + str( ethType )
1496 if ethSrc:
1497 cmd += " --ethSrc " + str( ethSrc )
1498 if ethDst:
1499 cmd += " --ethDst " + str( ethDst )
1500 if bandwidth:
1501 cmd += " --bandwidth " + str( bandwidth )
1502 if lambdaAlloc:
1503 cmd += " --lambda "
1504 if ipProto:
1505 cmd += " --ipProto " + str( ipProto )
1506 if ipSrc:
1507 cmd += " --ipSrc " + str( ipSrc )
1508 if ipDst:
1509 cmd += " --ipDst " + str( ipDst )
1510 if tcpSrc:
1511 cmd += " --tcpSrc " + str( tcpSrc )
1512 if tcpDst:
1513 cmd += " --tcpDst " + str( tcpDst )
1514 if setEthSrc:
1515 cmd += " --setEthSrc " + str( setEthSrc )
1516 if setEthDst:
1517 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001518 if vlanId:
1519 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001520
1521 # Check whether the user appended the port
1522 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001523
kelvin-onlabb9408212015-04-01 13:34:04 -07001524 if "/" in ingressDevice:
1525 cmd += " " + str( ingressDevice )
1526 else:
1527 if not portIngress:
1528 main.log.error( "You must specify " +
1529 "the Ingress port" )
1530 return main.FALSE
1531
1532 cmd += " " +\
1533 str( ingressDevice ) + "/" +\
1534 str( portIngress )
1535
1536 if portEgressList is None:
1537 for egressDevice in egressDeviceList:
1538 if "/" in egressDevice:
1539 cmd += " " + str( egressDevice )
1540 else:
1541 main.log.error( "You must specify " +
1542 "the egress port" )
1543 # TODO: perhaps more meaningful return
1544 return main.FALSE
1545 else:
1546 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001547 for egressDevice, portEgress in zip( egressDeviceList,
1548 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001549 cmd += " " + \
1550 str( egressDevice ) + "/" +\
1551 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001552 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001553 main.log.error( "Device list and port list does not " +
1554 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001555 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001556 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001557 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001558 # If error, return error message
1559 if re.search( "Error", handle ):
1560 main.log.error( "Error in adding singlepoint-to-multipoint " +
1561 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001562 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001563 else:
1564 match = re.search('id=0x([\da-f]+),', handle)
1565 if match:
1566 return match.group()[3:-1]
1567 else:
1568 main.log.error( "Error, intent ID not found" )
1569 return None
Jon Hallc6793552016-01-19 14:18:37 -08001570 except AssertionError:
1571 main.log.exception( "" )
1572 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001573 except TypeError:
1574 main.log.exception( self.name + ": Object not as expected" )
1575 return None
shahshreyad0c80432014-12-04 16:56:05 -08001576 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001577 main.log.error( self.name + ": EOF exception found" )
1578 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001579 main.cleanup()
1580 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001581 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001582 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001583 main.cleanup()
1584 main.exit()
1585
Hari Krishna9e232602015-04-13 17:29:08 -07001586 def addMplsIntent(
1587 self,
1588 ingressDevice,
1589 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001590 ingressPort="",
1591 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001592 ethType="",
1593 ethSrc="",
1594 ethDst="",
1595 bandwidth="",
1596 lambdaAlloc=False,
1597 ipProto="",
1598 ipSrc="",
1599 ipDst="",
1600 tcpSrc="",
1601 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001602 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001603 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001604 priority=""):
1605 """
1606 Required:
1607 * ingressDevice: device id of ingress device
1608 * egressDevice: device id of egress device
1609 Optional:
1610 * ethType: specify ethType
1611 * ethSrc: specify ethSrc ( i.e. src mac addr )
1612 * ethDst: specify ethDst ( i.e. dst mac addr )
1613 * bandwidth: specify bandwidth capacity of link
1614 * lambdaAlloc: if True, intent will allocate lambda
1615 for the specified intent
1616 * ipProto: specify ip protocol
1617 * ipSrc: specify ip source address
1618 * ipDst: specify ip destination address
1619 * tcpSrc: specify tcp source port
1620 * tcpDst: specify tcp destination port
1621 * ingressLabel: Ingress MPLS label
1622 * egressLabel: Egress MPLS label
1623 Description:
1624 Adds MPLS intent by
1625 specifying device id's and optional fields
1626 Returns:
1627 A string of the intent id or None on error
1628
1629 NOTE: This function may change depending on the
1630 options developers provide for MPLS
1631 intent via cli
1632 """
1633 try:
1634 # If there are no optional arguments
1635 if not ethType and not ethSrc and not ethDst\
1636 and not bandwidth and not lambdaAlloc \
1637 and not ipProto and not ipSrc and not ipDst \
1638 and not tcpSrc and not tcpDst and not ingressLabel \
1639 and not egressLabel:
1640 cmd = "add-mpls-intent"
1641
1642 else:
1643 cmd = "add-mpls-intent"
1644
1645 if ethType:
1646 cmd += " --ethType " + str( ethType )
1647 if ethSrc:
1648 cmd += " --ethSrc " + str( ethSrc )
1649 if ethDst:
1650 cmd += " --ethDst " + str( ethDst )
1651 if bandwidth:
1652 cmd += " --bandwidth " + str( bandwidth )
1653 if lambdaAlloc:
1654 cmd += " --lambda "
1655 if ipProto:
1656 cmd += " --ipProto " + str( ipProto )
1657 if ipSrc:
1658 cmd += " --ipSrc " + str( ipSrc )
1659 if ipDst:
1660 cmd += " --ipDst " + str( ipDst )
1661 if tcpSrc:
1662 cmd += " --tcpSrc " + str( tcpSrc )
1663 if tcpDst:
1664 cmd += " --tcpDst " + str( tcpDst )
1665 if ingressLabel:
1666 cmd += " --ingressLabel " + str( ingressLabel )
1667 if egressLabel:
1668 cmd += " --egressLabel " + str( egressLabel )
1669 if priority:
1670 cmd += " --priority " + str( priority )
1671
1672 # Check whether the user appended the port
1673 # or provided it as an input
1674 if "/" in ingressDevice:
1675 cmd += " " + str( ingressDevice )
1676 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001677 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001678 main.log.error( "You must specify the ingress port" )
1679 return None
1680
1681 cmd += " " + \
1682 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001683 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001684
1685 if "/" in egressDevice:
1686 cmd += " " + str( egressDevice )
1687 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001688 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001689 main.log.error( "You must specify the egress port" )
1690 return None
1691
1692 cmd += " " +\
1693 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001694 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001695
1696 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001697 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001698 # If error, return error message
1699 if re.search( "Error", handle ):
1700 main.log.error( "Error in adding mpls intent" )
1701 return None
1702 else:
1703 # TODO: print out all the options in this message?
1704 main.log.info( "MPLS intent installed between " +
1705 str( ingressDevice ) + " and " +
1706 str( egressDevice ) )
1707 match = re.search('id=0x([\da-f]+),', handle)
1708 if match:
1709 return match.group()[3:-1]
1710 else:
1711 main.log.error( "Error, intent ID not found" )
1712 return None
Jon Hallc6793552016-01-19 14:18:37 -08001713 except AssertionError:
1714 main.log.exception( "" )
1715 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001716 except TypeError:
1717 main.log.exception( self.name + ": Object not as expected" )
1718 return None
1719 except pexpect.EOF:
1720 main.log.error( self.name + ": EOF exception found" )
1721 main.log.error( self.name + ": " + self.handle.before )
1722 main.cleanup()
1723 main.exit()
1724 except Exception:
1725 main.log.exception( self.name + ": Uncaught exception!" )
1726 main.cleanup()
1727 main.exit()
1728
Jon Hallefbd9792015-03-05 16:11:36 -08001729 def removeIntent( self, intentId, app='org.onosproject.cli',
1730 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001731 """
shahshreya1c818fc2015-02-26 13:44:08 -08001732 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001733 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001734 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001735 -p or --purge: Purge the intent from the store after removal
1736
Jon Halle3f39ff2015-01-13 11:50:53 -08001737 Returns:
1738 main.False on error and
1739 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001740 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001741 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001742 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001743 if purge:
1744 cmdStr += " -p"
1745 if sync:
1746 cmdStr += " -s"
1747
1748 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001750 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001751 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001752 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001753 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001754 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001755 # TODO: Should this be main.TRUE
1756 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001757 except AssertionError:
1758 main.log.exception( "" )
1759 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001760 except TypeError:
1761 main.log.exception( self.name + ": Object not as expected" )
1762 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001764 main.log.error( self.name + ": EOF exception found" )
1765 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001766 main.cleanup()
1767 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001768 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001769 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001770 main.cleanup()
1771 main.exit()
1772
Jeremy42df2e72016-02-23 16:37:46 -08001773 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1774 """
1775 Description:
1776 Remove all the intents
1777 Optional args:-
1778 -s or --sync: Waits for the removal before returning
1779 -p or --purge: Purge the intent from the store after removal
1780 Returns:
1781 Returns main.TRUE if all intents are removed, otherwise returns
1782 main.FALSE; Returns None for exception
1783 """
1784 try:
1785 cmdStr = "remove-intent"
1786 if purge:
1787 cmdStr += " -p"
1788 if sync:
1789 cmdStr += " -s"
1790
1791 cmdStr += " " + app
1792 handle = self.sendline( cmdStr )
1793 assert "Command not found:" not in handle, handle
1794 if re.search( "Error", handle ):
1795 main.log.error( "Error in removing intent" )
1796 return main.FALSE
1797 else:
1798 return main.TRUE
1799 except AssertionError:
1800 main.log.exception( "" )
1801 return None
1802 except TypeError:
1803 main.log.exception( self.name + ": Object not as expected" )
1804 return None
1805 except pexpect.EOF:
1806 main.log.error( self.name + ": EOF exception found" )
1807 main.log.error( self.name + ": " + self.handle.before )
1808 main.cleanup()
1809 main.exit()
1810 except Exception:
1811 main.log.exception( self.name + ": Uncaught exception!" )
1812 main.cleanup()
1813 main.exit()
1814
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001815 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001816 """
1817 Purges all WITHDRAWN Intents
1818 """
1819 try:
1820 cmdStr = "purge-intents"
1821 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001822 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001823 if re.search( "Error", handle ):
1824 main.log.error( "Error in purging intents" )
1825 return main.FALSE
1826 else:
1827 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001828 except AssertionError:
1829 main.log.exception( "" )
1830 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001831 except TypeError:
1832 main.log.exception( self.name + ": Object not as expected" )
1833 return None
1834 except pexpect.EOF:
1835 main.log.error( self.name + ": EOF exception found" )
1836 main.log.error( self.name + ": " + self.handle.before )
1837 main.cleanup()
1838 main.exit()
1839 except Exception:
1840 main.log.exception( self.name + ": Uncaught exception!" )
1841 main.cleanup()
1842 main.exit()
1843
kelvin-onlabd3b64892015-01-20 13:26:24 -08001844 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001845 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 NOTE: This method should be used after installing application:
1847 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001848 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001849 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001850 Description:
1851 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001852 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001853 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001854 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001855 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001856 cmdStr += " -j"
1857 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001858 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001859 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001860 except AssertionError:
1861 main.log.exception( "" )
1862 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001863 except TypeError:
1864 main.log.exception( self.name + ": Object not as expected" )
1865 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001867 main.log.error( self.name + ": EOF exception found" )
1868 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001869 main.cleanup()
1870 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001871 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001872 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001873 main.cleanup()
1874 main.exit()
1875
pingping-lin54b03372015-08-13 14:43:10 -07001876 def ipv4RouteNumber( self ):
1877 """
1878 NOTE: This method should be used after installing application:
1879 onos-app-sdnip
1880 Description:
1881 Obtain the total IPv4 routes number in the system
1882 """
1883 try:
1884 cmdStr = "routes -s -j"
1885 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001886 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001887 jsonResult = json.loads( handle )
1888 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001889 except AssertionError:
1890 main.log.exception( "" )
1891 return None
1892 except ( TypeError, ValueError ):
1893 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001894 return None
1895 except pexpect.EOF:
1896 main.log.error( self.name + ": EOF exception found" )
1897 main.log.error( self.name + ": " + self.handle.before )
1898 main.cleanup()
1899 main.exit()
1900 except Exception:
1901 main.log.exception( self.name + ": Uncaught exception!" )
1902 main.cleanup()
1903 main.exit()
1904
pingping-lin8244a3b2015-09-16 13:36:56 -07001905 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001906 """
andrewonlabe6745342014-10-17 14:29:13 -04001907 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001908 Obtain intents from the ONOS cli.
1909 Optional:
1910 * jsonFormat: Enable output formatting in json, default to True
1911 * summary: Whether only output the intent summary, defaults to False
1912 * type: Only output a certain type of intent. This options is valid
1913 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001914 """
andrewonlabe6745342014-10-17 14:29:13 -04001915 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001916 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001917 if summary:
1918 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001919 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001920 cmdStr += " -j"
1921 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001922 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001923 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001924 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001925 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001926 else:
Jon Hallff566d52016-01-15 14:45:36 -08001927 intentType = ""
1928 # IF we want the summary of a specific intent type
1929 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001930 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001931 if intentType in jsonResult.keys():
1932 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001933 else:
Jon Hallff566d52016-01-15 14:45:36 -08001934 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001935 return handle
1936 else:
1937 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001938 except AssertionError:
1939 main.log.exception( "" )
1940 return None
1941 except ( TypeError, ValueError ):
1942 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001943 return None
1944 except pexpect.EOF:
1945 main.log.error( self.name + ": EOF exception found" )
1946 main.log.error( self.name + ": " + self.handle.before )
1947 main.cleanup()
1948 main.exit()
1949 except Exception:
1950 main.log.exception( self.name + ": Uncaught exception!" )
1951 main.cleanup()
1952 main.exit()
1953
kelvin-onlab54400a92015-02-26 18:05:51 -08001954 def getIntentState(self, intentsId, intentsJson=None):
1955 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001956 Check intent state.
1957 Accepts a single intent ID (string type) or a list of intent IDs.
1958 Returns the state(string type) of the id if a single intent ID is
1959 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001960 Returns a dictionary with intent IDs as the key and its
1961 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001962 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001963 intentId: intent ID (string type)
1964 intentsJson: parsed json object from the onos:intents api
1965 Returns:
1966 state = An intent's state- INSTALL,WITHDRAWN etc.
1967 stateDict = Dictionary of intent's state. intent ID as the keys and
1968 state as the values.
1969 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001970 try:
1971 state = "State is Undefined"
1972 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001973 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001974 else:
Jon Hallc6793552016-01-19 14:18:37 -08001975 rawJson = intentsJson
1976 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001977 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001978 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001979 if intentsId == intent[ 'id' ]:
1980 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001981 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001982 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1983 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001984 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001985 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001986 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001987 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001988 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001989 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001990 if intentsId[ i ] == intents[ 'id' ]:
1991 stateDict[ 'state' ] = intents[ 'state' ]
1992 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001993 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001994 break
Jon Hallefbd9792015-03-05 16:11:36 -08001995 if len( intentsId ) != len( dictList ):
1996 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001997 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001998 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001999 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002000 return None
Jon Hallc6793552016-01-19 14:18:37 -08002001 except ( TypeError, ValueError ):
2002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002009 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002010 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002011 main.cleanup()
2012 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002013
kelvin-onlabf512e942015-06-08 19:42:59 -07002014 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002015 """
2016 Description:
2017 Check intents state
2018 Required:
2019 intentsId - List of intents ID to be checked
2020 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002021 expectedState - Check the expected state(s) of each intents
2022 state in the list.
2023 *NOTE: You can pass in a list of expected state,
2024 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002025 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002026 Returns main.TRUE only if all intent are the same as expected states
2027 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002028 """
2029 try:
2030 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002031 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002032 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002033 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002034 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002035 "getting intents state" )
2036 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002037
2038 if isinstance( expectedState, types.StringType ):
2039 for intents in intentsDict:
2040 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002041 main.log.debug( self.name + " : Intent ID - " +
2042 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002043 " actual state = " +
2044 intents.get( 'state' )
2045 + " does not equal expected state = "
2046 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002047 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002048
2049 elif isinstance( expectedState, types.ListType ):
2050 for intents in intentsDict:
2051 if not any( state == intents.get( 'state' ) for state in
2052 expectedState ):
2053 main.log.debug( self.name + " : Intent ID - " +
2054 intents.get( 'id' ) +
2055 " actual state = " +
2056 intents.get( 'state' ) +
2057 " does not equal expected states = "
2058 + str( expectedState ) )
2059 returnValue = main.FALSE
2060
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002061 if returnValue == main.TRUE:
2062 main.log.info( self.name + ": All " +
2063 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002064 " intents are in " + str( expectedState ) +
2065 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002066 return returnValue
2067 except TypeError:
2068 main.log.exception( self.name + ": Object not as expected" )
2069 return None
2070 except pexpect.EOF:
2071 main.log.error( self.name + ": EOF exception found" )
2072 main.log.error( self.name + ": " + self.handle.before )
2073 main.cleanup()
2074 main.exit()
2075 except Exception:
2076 main.log.exception( self.name + ": Uncaught exception!" )
2077 main.cleanup()
2078 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002079
GlennRCed771242016-01-13 17:02:47 -08002080 def checkIntentSummary( self, timeout=60 ):
2081 """
2082 Description:
2083 Check the number of installed intents.
2084 Optional:
2085 timeout - the timeout for pexcept
2086 Return:
2087 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2088 , otherwise, returns main.FALSE.
2089 """
2090
2091 try:
2092 cmd = "intents -s -j"
2093
2094 # Check response if something wrong
2095 response = self.sendline( cmd, timeout=timeout )
2096 if response == None:
2097 return main.False
2098 response = json.loads( response )
2099
2100 # get total and installed number, see if they are match
2101 allState = response.get( 'all' )
2102 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002103 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002104 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002105 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002106 return main.FALSE
2107
Jon Hallc6793552016-01-19 14:18:37 -08002108 except ( TypeError, ValueError ):
2109 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002110 return None
2111 except pexpect.EOF:
2112 main.log.error( self.name + ": EOF exception found" )
2113 main.log.error( self.name + ": " + self.handle.before )
2114 main.cleanup()
2115 main.exit()
2116 except Exception:
2117 main.log.exception( self.name + ": Uncaught exception!" )
2118 main.cleanup()
2119 main.exit()
2120
2121 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002122 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002123 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002125 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002126 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002127 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002128 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002129 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002130 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002131 cmdStr += " -j "
2132 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002133 handle = self.sendline( cmdStr, timeout=timeout )
2134 assert "Command not found:" not in handle, handle
2135 if re.search( "Error:", handle ):
2136 main.log.error( self.name + ": flows() response: " +
2137 str( handle ) )
2138 return handle
2139 except AssertionError:
2140 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002141 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002142 except TypeError:
2143 main.log.exception( self.name + ": Object not as expected" )
2144 return None
Jon Hallc6793552016-01-19 14:18:37 -08002145 except pexpect.TIMEOUT:
2146 main.log.error( self.name + ": ONOS timeout" )
2147 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002148 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002149 main.log.error( self.name + ": EOF exception found" )
2150 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002151 main.cleanup()
2152 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002154 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002155 main.cleanup()
2156 main.exit()
2157
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002158 def checkFlowCount(self, min=0, timeout=60 ):
2159 count = int(self.getTotalFlowsNum( timeout=timeout ))
2160 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002161
Jon Hallc6793552016-01-19 14:18:37 -08002162 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002163 """
2164 Description:
GlennRCed771242016-01-13 17:02:47 -08002165 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002166 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2167 if the count of those states is 0, which means all current flows
2168 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002169 Optional:
GlennRCed771242016-01-13 17:02:47 -08002170 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002171 Return:
2172 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002173 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002174 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002175 """
2176 try:
GlennRCed771242016-01-13 17:02:47 -08002177 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2178 checkedStates = []
2179 statesCount = [0, 0, 0, 0]
2180 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002181 rawFlows = self.flows( state=s, timeout = timeout )
2182 checkedStates.append( json.loads( rawFlows ) )
2183 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002184 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002185 try:
2186 statesCount[i] += int( c.get( "flowCount" ) )
2187 except TypeError:
2188 main.log.exception( "Json object not as expected" )
2189 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002190
GlennRCed771242016-01-13 17:02:47 -08002191 # We want to count PENDING_ADD if isPENDING is true
2192 if isPENDING:
2193 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2194 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002195 else:
GlennRCed771242016-01-13 17:02:47 -08002196 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2197 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002198 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002199 except ( TypeError, ValueError ):
2200 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002201 return None
2202 except pexpect.EOF:
2203 main.log.error( self.name + ": EOF exception found" )
2204 main.log.error( self.name + ": " + self.handle.before )
2205 main.cleanup()
2206 main.exit()
2207 except Exception:
2208 main.log.exception( self.name + ": Uncaught exception!" )
2209 main.cleanup()
2210 main.exit()
2211
GlennRCed771242016-01-13 17:02:47 -08002212 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2213 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002214 """
andrewonlab87852b02014-11-19 18:44:19 -05002215 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002216 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002217 a specific point-to-point intent definition
2218 Required:
GlennRCed771242016-01-13 17:02:47 -08002219 * ingress: specify source dpid
2220 * egress: specify destination dpid
2221 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002222 Optional:
GlennRCed771242016-01-13 17:02:47 -08002223 * offset: the keyOffset is where the next batch of intents
2224 will be installed
2225 Returns: If failed to push test intents, it will returen None,
2226 if successful, return true.
2227 Timeout expection will return None,
2228 TypeError will return false
2229 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002230 """
andrewonlab87852b02014-11-19 18:44:19 -05002231 try:
GlennRCed771242016-01-13 17:02:47 -08002232 if background:
2233 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002234 else:
GlennRCed771242016-01-13 17:02:47 -08002235 back = ""
2236 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002237 ingress,
2238 egress,
2239 batchSize,
2240 offset,
2241 back )
GlennRCed771242016-01-13 17:02:47 -08002242 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002243 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002244 main.log.info( response )
2245 if response == None:
2246 return None
2247
2248 # TODO: We should handle if there is failure in installation
2249 return main.TRUE
2250
Jon Hallc6793552016-01-19 14:18:37 -08002251 except AssertionError:
2252 main.log.exception( "" )
2253 return None
GlennRCed771242016-01-13 17:02:47 -08002254 except pexpect.TIMEOUT:
2255 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002256 return None
andrewonlab87852b02014-11-19 18:44:19 -05002257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002260 main.cleanup()
2261 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002262 except TypeError:
2263 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002264 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002265 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002266 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002267 main.cleanup()
2268 main.exit()
2269
YPZhangf6f14a02016-01-28 15:17:31 -08002270 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002271 """
2272 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002273 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002274 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002275 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002276 """
YPZhange3109a72016-02-02 11:25:37 -08002277
YPZhangb5d3f832016-01-23 22:54:26 -08002278 try:
YPZhange3109a72016-02-02 11:25:37 -08002279 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002280 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002281 totalFlows = self.sendline( cmd, timeout=timeout )
2282
2283 if totalFlows == None:
2284 # if timeout, we will get total number of all flows, and subtract other states
2285 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2286 checkedStates = []
2287 totalFlows = 0
2288 statesCount = [0, 0, 0, 0]
2289
2290 # get total flows from summary
2291 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2292 totalFlows = int( response.get("flows") )
2293
2294 for s in states:
2295 rawFlows = self.flows( state=s, timeout = timeout )
2296 if rawFlows == None:
2297 # if timeout, return the total flows number from summary command
2298 return totalFlows
2299 checkedStates.append( json.loads( rawFlows ) )
2300
2301 # Calculate ADDED flows number, equal total subtracts others
2302 for i in range( len( states ) ):
2303 for c in checkedStates[i]:
2304 try:
2305 statesCount[i] += int( c.get( "flowCount" ) )
2306 except TypeError:
2307 main.log.exception( "Json object not as expected" )
2308 totalFlows = totalFlows - int( statesCount[i] )
2309 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2310
2311 return totalFlows
2312
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002313 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002314
YPZhangb5d3f832016-01-23 22:54:26 -08002315 except TypeError:
2316 main.log.exception( self.name + ": Object not as expected" )
2317 return None
2318 except pexpect.EOF:
2319 main.log.error( self.name + ": EOF exception found" )
2320 main.log.error( self.name + ": " + self.handle.before )
2321 main.cleanup()
2322 main.exit()
2323 except Exception:
2324 main.log.exception( self.name + ": Uncaught exception!" )
2325 main.cleanup()
2326 main.exit()
2327
2328 def getTotalIntentsNum( self ):
2329 """
2330 Description:
2331 Get the total number of intents, include every states.
2332 Return:
2333 The number of intents
2334 """
2335 try:
2336 cmd = "summary -j"
2337 response = self.sendline( cmd )
2338 if response == None:
2339 return -1
2340 response = json.loads( response )
2341 return int( response.get("intents") )
2342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
2345 except pexpect.EOF:
2346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
2348 main.cleanup()
2349 main.exit()
2350 except Exception:
2351 main.log.exception( self.name + ": Uncaught exception!" )
2352 main.cleanup()
2353 main.exit()
2354
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002356 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002357 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002358 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002359 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002360 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002361 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002362 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002363 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002364 cmdStr += " -j"
2365 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002366 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002367 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002368 except AssertionError:
2369 main.log.exception( "" )
2370 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002371 except TypeError:
2372 main.log.exception( self.name + ": Object not as expected" )
2373 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002374 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002375 main.log.error( self.name + ": EOF exception found" )
2376 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002377 main.cleanup()
2378 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002379 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002380 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002381 main.cleanup()
2382 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002383
kelvin-onlabd3b64892015-01-20 13:26:24 -08002384 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002385 """
2386 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002387 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002388 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002389 """
andrewonlab867212a2014-10-22 20:13:38 -04002390 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002391 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002392 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002393 cmdStr += " -j"
2394 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002395 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002396 if handle:
2397 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002398 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002399 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002400 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002401 else:
2402 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002403 except AssertionError:
2404 main.log.exception( "" )
2405 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002406 except TypeError:
2407 main.log.exception( self.name + ": Object not as expected" )
2408 return None
andrewonlab867212a2014-10-22 20:13:38 -04002409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002410 main.log.error( self.name + ": EOF exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002412 main.cleanup()
2413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002416 main.cleanup()
2417 main.exit()
2418
kelvin8ec71442015-01-15 16:57:00 -08002419 # Wrapper functions ****************
2420 # Wrapper functions use existing driver
2421 # functions and extends their use case.
2422 # For example, we may use the output of
2423 # a normal driver function, and parse it
2424 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002425
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002427 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002428 Description:
2429 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002430 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002431 try:
kelvin8ec71442015-01-15 16:57:00 -08002432 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002433 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002434 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002435
kelvin8ec71442015-01-15 16:57:00 -08002436 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002437 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2438 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002439 match = re.search('id=0x([\da-f]+),', intents)
2440 if match:
2441 tmpId = match.group()[3:-1]
2442 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002443 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002444
Jon Halld4d4b372015-01-28 16:02:41 -08002445 except TypeError:
2446 main.log.exception( self.name + ": Object not as expected" )
2447 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002449 main.log.error( self.name + ": EOF exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002451 main.cleanup()
2452 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002454 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002455 main.cleanup()
2456 main.exit()
2457
Jon Hall30b82fa2015-03-04 17:15:43 -08002458 def FlowAddedCount( self, deviceId ):
2459 """
2460 Determine the number of flow rules for the given device id that are
2461 in the added state
2462 """
2463 try:
2464 cmdStr = "flows any " + str( deviceId ) + " | " +\
2465 "grep 'state=ADDED' | wc -l"
2466 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002467 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002468 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002469 except AssertionError:
2470 main.log.exception( "" )
2471 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002472 except pexpect.EOF:
2473 main.log.error( self.name + ": EOF exception found" )
2474 main.log.error( self.name + ": " + self.handle.before )
2475 main.cleanup()
2476 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002477 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002478 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002479 main.cleanup()
2480 main.exit()
2481
kelvin-onlabd3b64892015-01-20 13:26:24 -08002482 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002483 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002484 Use 'devices' function to obtain list of all devices
2485 and parse the result to obtain a list of all device
2486 id's. Returns this list. Returns empty list if no
2487 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002488 List is ordered sequentially
2489
andrewonlab3e15ead2014-10-15 14:21:34 -04002490 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002491 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002492 the ids. By obtaining the list of device ids on the fly,
2493 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002494 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002495 try:
kelvin8ec71442015-01-15 16:57:00 -08002496 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002497 devicesStr = self.devices( jsonFormat=False )
2498 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002499
kelvin-onlabd3b64892015-01-20 13:26:24 -08002500 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002501 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002502 return idList
kelvin8ec71442015-01-15 16:57:00 -08002503
2504 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002505 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002506 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002507 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002508 # Split list further into arguments before and after string
2509 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 # append to idList
2511 for arg in tempList:
2512 idList.append( arg.split( "id=" )[ 1 ] )
2513 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002514
Jon Halld4d4b372015-01-28 16:02:41 -08002515 except TypeError:
2516 main.log.exception( self.name + ": Object not as expected" )
2517 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002518 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002519 main.log.error( self.name + ": EOF exception found" )
2520 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002521 main.cleanup()
2522 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002523 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002524 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002525 main.cleanup()
2526 main.exit()
2527
kelvin-onlabd3b64892015-01-20 13:26:24 -08002528 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002529 """
andrewonlab7c211572014-10-15 16:45:20 -04002530 Uses 'nodes' function to obtain list of all nodes
2531 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002532 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002533 Returns:
2534 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002535 """
andrewonlab7c211572014-10-15 16:45:20 -04002536 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002537 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002538 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002539 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002540 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002542 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002543 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002544 nodesJson = json.loads( nodesStr )
2545 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002546 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002547 except ( TypeError, ValueError ):
2548 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002549 return None
andrewonlab7c211572014-10-15 16:45:20 -04002550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002551 main.log.error( self.name + ": EOF exception found" )
2552 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002553 main.cleanup()
2554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002556 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002557 main.cleanup()
2558 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002559
kelvin-onlabd3b64892015-01-20 13:26:24 -08002560 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002561 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002562 Return the first device from the devices api whose 'id' contains 'dpid'
2563 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002564 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002565 try:
kelvin8ec71442015-01-15 16:57:00 -08002566 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002567 return None
2568 else:
kelvin8ec71442015-01-15 16:57:00 -08002569 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002570 rawDevices = self.devices()
2571 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002572 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002573 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002574 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2575 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002576 return device
2577 return None
Jon Hallc6793552016-01-19 14:18:37 -08002578 except ( TypeError, ValueError ):
2579 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002580 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002582 main.log.error( self.name + ": EOF exception found" )
2583 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002584 main.cleanup()
2585 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002586 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002587 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002588 main.cleanup()
2589 main.exit()
2590
You Wang24139872016-05-03 11:48:47 -07002591 def getTopology( self, topologyOutput ):
2592 """
2593 Definition:
2594 Loads a json topology output
2595 Return:
2596 topology = current ONOS topology
2597 """
2598 import json
2599 try:
2600 # either onos:topology or 'topology' will work in CLI
2601 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002602 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002603 return topology
2604 except pexpect.EOF:
2605 main.log.error( self.name + ": EOF exception found" )
2606 main.log.error( self.name + ": " + self.handle.before )
2607 main.cleanup()
2608 main.exit()
2609 except Exception:
2610 main.log.exception( self.name + ": Uncaught exception!" )
2611 main.cleanup()
2612 main.exit()
2613
2614 def checkStatus(
2615 self,
2616 topologyResult,
2617 numoswitch,
2618 numolink,
2619 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002620 """
Jon Hallefbd9792015-03-05 16:11:36 -08002621 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002622 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002623 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002624
You Wang24139872016-05-03 11:48:47 -07002625 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002626 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002627 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002628 logLevel = level to log to.
2629 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002630
Jon Hallefbd9792015-03-05 16:11:36 -08002631 Returns: main.TRUE if the number of switches and links are correct,
2632 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002633 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002634 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002635 try:
You Wang24139872016-05-03 11:48:47 -07002636 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002637 if topology == {}:
2638 return main.ERROR
2639 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002640 # Is the number of switches is what we expected
2641 devices = topology.get( 'devices', False )
2642 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002643 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002644 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002645 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002646 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002647 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002648 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002649 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002650 output = output + "The number of links and switches match "\
2651 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002652 result = main.TRUE
2653 else:
You Wang24139872016-05-03 11:48:47 -07002654 output = output + \
2655 "The number of links and switches does not match " + \
2656 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002657 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002658 output = output + "\n ONOS sees %i devices" % int( devices )
2659 output = output + " (%i expected) " % int( numoswitch )
2660 output = output + "and %i links " % int( links )
2661 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002663 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002665 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002666 else:
You Wang24139872016-05-03 11:48:47 -07002667 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002668 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002669 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002670 main.log.error( self.name + ": EOF exception found" )
2671 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002672 main.cleanup()
2673 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002674 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002675 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002676 main.cleanup()
2677 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002678
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002680 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002681 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 deviceId must be the id of a device as seen in the onos devices command
2683 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002684 role must be either master, standby, or none
2685
Jon Halle3f39ff2015-01-13 11:50:53 -08002686 Returns:
2687 main.TRUE or main.FALSE based on argument verification and
2688 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002689 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002690 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002691 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002692 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 cmdStr = "device-role " +\
2694 str( deviceId ) + " " +\
2695 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002696 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002698 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002699 if re.search( "Error", handle ):
2700 # end color output to escape any colours
2701 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002702 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002703 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002704 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002705 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002706 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002707 main.log.error( "Invalid 'role' given to device_role(). " +
2708 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002709 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002710 except AssertionError:
2711 main.log.exception( "" )
2712 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002713 except TypeError:
2714 main.log.exception( self.name + ": Object not as expected" )
2715 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002716 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002717 main.log.error( self.name + ": EOF exception found" )
2718 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002719 main.cleanup()
2720 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002721 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002722 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002723 main.cleanup()
2724 main.exit()
2725
kelvin-onlabd3b64892015-01-20 13:26:24 -08002726 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002727 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002728 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002729 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002731 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002732 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002733 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002734 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002735 cmdStr += " -j"
2736 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002737 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002738 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002739 except AssertionError:
2740 main.log.exception( "" )
2741 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002742 except TypeError:
2743 main.log.exception( self.name + ": Object not as expected" )
2744 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002746 main.log.error( self.name + ": EOF exception found" )
2747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002748 main.cleanup()
2749 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002750 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002751 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002752 main.cleanup()
2753 main.exit()
2754
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002756 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002757 CLI command to get the current leader for the Election test application
2758 NOTE: Requires installation of the onos-app-election feature
2759 Returns: Node IP of the leader if one exists
2760 None if none exists
2761 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002762 """
Jon Hall94fd0472014-12-08 11:52:42 -08002763 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002764 cmdStr = "election-test-leader"
2765 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002766 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002767 # Leader
2768 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002769 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002770 nodeSearch = re.search( leaderPattern, response )
2771 if nodeSearch:
2772 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002773 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002774 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002775 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002776 # no leader
2777 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002778 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002779 nullSearch = re.search( nullPattern, response )
2780 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002781 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002782 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002783 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002784 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002785 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002786 if re.search( errorPattern, response ):
2787 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002788 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002789 return main.FALSE
2790 else:
Jon Hall390696c2015-05-05 17:13:41 -07002791 main.log.error( "Error in electionTestLeader on " + self.name +
2792 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002793 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002794 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002795 except AssertionError:
2796 main.log.exception( "" )
2797 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002798 except TypeError:
2799 main.log.exception( self.name + ": Object not as expected" )
2800 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002801 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002802 main.log.error( self.name + ": EOF exception found" )
2803 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002804 main.cleanup()
2805 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002806 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002807 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002808 main.cleanup()
2809 main.exit()
2810
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002812 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002813 CLI command to run for leadership of the Election test application.
2814 NOTE: Requires installation of the onos-app-election feature
2815 Returns: Main.TRUE on success
2816 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002817 """
Jon Hall94fd0472014-12-08 11:52:42 -08002818 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002819 cmdStr = "election-test-run"
2820 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002821 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002822 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002823 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002824 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002825 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002826 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002827 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002828 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002829 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002830 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002831 errorPattern = "Command\snot\sfound"
2832 if re.search( errorPattern, response ):
2833 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002834 return main.FALSE
2835 else:
Jon Hall390696c2015-05-05 17:13:41 -07002836 main.log.error( "Error in electionTestRun on " + self.name +
2837 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002838 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002839 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002840 except AssertionError:
2841 main.log.exception( "" )
2842 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002843 except TypeError:
2844 main.log.exception( self.name + ": Object not as expected" )
2845 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002846 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002847 main.log.error( self.name + ": EOF exception found" )
2848 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002849 main.cleanup()
2850 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002851 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002852 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002853 main.cleanup()
2854 main.exit()
2855
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002857 """
Jon Hall94fd0472014-12-08 11:52:42 -08002858 * CLI command to withdraw the local node from leadership election for
2859 * the Election test application.
2860 #NOTE: Requires installation of the onos-app-election feature
2861 Returns: Main.TRUE on success
2862 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002863 """
Jon Hall94fd0472014-12-08 11:52:42 -08002864 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002865 cmdStr = "election-test-withdraw"
2866 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002867 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002868 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002869 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002870 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002871 if re.search( successPattern, response ):
2872 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002873 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002874 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002875 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002876 errorPattern = "Command\snot\sfound"
2877 if re.search( errorPattern, response ):
2878 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002879 return main.FALSE
2880 else:
Jon Hall390696c2015-05-05 17:13:41 -07002881 main.log.error( "Error in electionTestWithdraw on " +
2882 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002883 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002884 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002885 except AssertionError:
2886 main.log.exception( "" )
2887 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002888 except TypeError:
2889 main.log.exception( self.name + ": Object not as expected" )
2890 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002891 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002892 main.log.error( self.name + ": EOF exception found" )
2893 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002894 main.cleanup()
2895 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002896 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002897 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002898 main.cleanup()
2899 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002900
kelvin8ec71442015-01-15 16:57:00 -08002901 def getDevicePortsEnabledCount( self, dpid ):
2902 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002903 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002904 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002905 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002906 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2908 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002909 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002910 if re.search( "No such device", output ):
2911 main.log.error( "Error in getting ports" )
2912 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002913 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002914 return output
Jon Hallc6793552016-01-19 14:18:37 -08002915 except AssertionError:
2916 main.log.exception( "" )
2917 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002918 except TypeError:
2919 main.log.exception( self.name + ": Object not as expected" )
2920 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002921 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002922 main.log.error( self.name + ": EOF exception found" )
2923 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002924 main.cleanup()
2925 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002926 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002927 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002928 main.cleanup()
2929 main.exit()
2930
kelvin8ec71442015-01-15 16:57:00 -08002931 def getDeviceLinksActiveCount( self, dpid ):
2932 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002933 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002934 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002935 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002936 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2938 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002939 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002940 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002941 main.log.error( "Error in getting ports " )
2942 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002943 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002944 return output
Jon Hallc6793552016-01-19 14:18:37 -08002945 except AssertionError:
2946 main.log.exception( "" )
2947 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002948 except TypeError:
2949 main.log.exception( self.name + ": Object not as expected" )
2950 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002951 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002952 main.log.error( self.name + ": EOF exception found" )
2953 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002954 main.cleanup()
2955 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002956 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002957 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002958 main.cleanup()
2959 main.exit()
2960
kelvin8ec71442015-01-15 16:57:00 -08002961 def getAllIntentIds( self ):
2962 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002963 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002964 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002965 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002966 cmdStr = "onos:intents | grep id="
2967 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002968 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002969 if re.search( "Error", output ):
2970 main.log.error( "Error in getting ports" )
2971 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002972 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002973 return output
Jon Hallc6793552016-01-19 14:18:37 -08002974 except AssertionError:
2975 main.log.exception( "" )
2976 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002977 except TypeError:
2978 main.log.exception( self.name + ": Object not as expected" )
2979 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002980 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002981 main.log.error( self.name + ": EOF exception found" )
2982 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002983 main.cleanup()
2984 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002985 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002986 main.log.exception( self.name + ": Uncaught exception!" )
2987 main.cleanup()
2988 main.exit()
2989
Jon Hall73509952015-02-24 16:42:56 -08002990 def intentSummary( self ):
2991 """
Jon Hallefbd9792015-03-05 16:11:36 -08002992 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002993 """
2994 try:
2995 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002996 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002997 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002998 states.append( intent.get( 'state', None ) )
2999 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003000 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003001 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003002 except ( TypeError, ValueError ):
3003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003004 return None
3005 except pexpect.EOF:
3006 main.log.error( self.name + ": EOF exception found" )
3007 main.log.error( self.name + ": " + self.handle.before )
3008 main.cleanup()
3009 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003010 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003011 main.log.exception( self.name + ": Uncaught exception!" )
3012 main.cleanup()
3013 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003014
Jon Hall61282e32015-03-19 11:34:11 -07003015 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003016 """
3017 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003018 Optional argument:
3019 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003020 """
Jon Hall63604932015-02-26 17:09:50 -08003021 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003022 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003023 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003024 cmdStr += " -j"
3025 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003026 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003027 return output
Jon Hallc6793552016-01-19 14:18:37 -08003028 except AssertionError:
3029 main.log.exception( "" )
3030 return None
Jon Hall63604932015-02-26 17:09:50 -08003031 except TypeError:
3032 main.log.exception( self.name + ": Object not as expected" )
3033 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003034 except pexpect.EOF:
3035 main.log.error( self.name + ": EOF exception found" )
3036 main.log.error( self.name + ": " + self.handle.before )
3037 main.cleanup()
3038 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003039 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003040 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003041 main.cleanup()
3042 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003043
acsmarsa4a4d1e2015-07-10 16:01:24 -07003044 def leaderCandidates( self, jsonFormat=True ):
3045 """
3046 Returns the output of the leaders -c command.
3047 Optional argument:
3048 * jsonFormat - boolean indicating if you want output in json
3049 """
3050 try:
3051 cmdStr = "onos:leaders -c"
3052 if jsonFormat:
3053 cmdStr += " -j"
3054 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003055 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003056 return output
Jon Hallc6793552016-01-19 14:18:37 -08003057 except AssertionError:
3058 main.log.exception( "" )
3059 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003060 except TypeError:
3061 main.log.exception( self.name + ": Object not as expected" )
3062 return None
3063 except pexpect.EOF:
3064 main.log.error( self.name + ": EOF exception found" )
3065 main.log.error( self.name + ": " + self.handle.before )
3066 main.cleanup()
3067 main.exit()
3068 except Exception:
3069 main.log.exception( self.name + ": Uncaught exception!" )
3070 main.cleanup()
3071 main.exit()
3072
Jon Hallc6793552016-01-19 14:18:37 -08003073 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003074 """
3075 Returns a list in format [leader,candidate1,candidate2,...] for a given
3076 topic parameter and an empty list if the topic doesn't exist
3077 If no leader is elected leader in the returned list will be "none"
3078 Returns None if there is a type error processing the json object
3079 """
3080 try:
Jon Hall6e709752016-02-01 13:38:46 -08003081 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003082 rawOutput = self.sendline( cmdStr )
3083 assert "Command not found:" not in rawOutput, rawOutput
3084 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003085 results = []
3086 for dict in output:
3087 if dict["topic"] == topic:
3088 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003089 candidates = re.split( ", ", dict["candidates"][1:-1] )
3090 results.append( leader )
3091 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003092 return results
Jon Hallc6793552016-01-19 14:18:37 -08003093 except AssertionError:
3094 main.log.exception( "" )
3095 return None
3096 except ( TypeError, ValueError ):
3097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003098 return None
3099 except pexpect.EOF:
3100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
3102 main.cleanup()
3103 main.exit()
3104 except Exception:
3105 main.log.exception( self.name + ": Uncaught exception!" )
3106 main.cleanup()
3107 main.exit()
3108
Jon Hall61282e32015-03-19 11:34:11 -07003109 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003110 """
3111 Returns the output of the intent Pending map.
3112 """
Jon Hall63604932015-02-26 17:09:50 -08003113 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003114 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003115 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003116 cmdStr += " -j"
3117 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003118 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003119 return output
Jon Hallc6793552016-01-19 14:18:37 -08003120 except AssertionError:
3121 main.log.exception( "" )
3122 return None
Jon Hall63604932015-02-26 17:09:50 -08003123 except TypeError:
3124 main.log.exception( self.name + ": Object not as expected" )
3125 return None
3126 except pexpect.EOF:
3127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
3129 main.cleanup()
3130 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003131 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003132 main.log.exception( self.name + ": Uncaught exception!" )
3133 main.cleanup()
3134 main.exit()
3135
Jon Hall61282e32015-03-19 11:34:11 -07003136 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003137 """
3138 Returns the output of the raft partitions command for ONOS.
3139 """
Jon Hall61282e32015-03-19 11:34:11 -07003140 # Sample JSON
3141 # {
3142 # "leader": "tcp://10.128.30.11:7238",
3143 # "members": [
3144 # "tcp://10.128.30.11:7238",
3145 # "tcp://10.128.30.17:7238",
3146 # "tcp://10.128.30.13:7238",
3147 # ],
3148 # "name": "p1",
3149 # "term": 3
3150 # },
Jon Hall63604932015-02-26 17:09:50 -08003151 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003152 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003153 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003154 cmdStr += " -j"
3155 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003156 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003157 return output
Jon Hallc6793552016-01-19 14:18:37 -08003158 except AssertionError:
3159 main.log.exception( "" )
3160 return None
Jon Hall63604932015-02-26 17:09:50 -08003161 except TypeError:
3162 main.log.exception( self.name + ": Object not as expected" )
3163 return None
3164 except pexpect.EOF:
3165 main.log.error( self.name + ": EOF exception found" )
3166 main.log.error( self.name + ": " + self.handle.before )
3167 main.cleanup()
3168 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003169 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003170 main.log.exception( self.name + ": Uncaught exception!" )
3171 main.cleanup()
3172 main.exit()
3173
Jon Hallbe379602015-03-24 13:39:32 -07003174 def apps( self, jsonFormat=True ):
3175 """
3176 Returns the output of the apps command for ONOS. This command lists
3177 information about installed ONOS applications
3178 """
3179 # Sample JSON object
3180 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3181 # "description":"ONOS OpenFlow protocol southbound providers",
3182 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3183 # "features":"[onos-openflow]","state":"ACTIVE"}]
3184 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003185 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003186 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003187 cmdStr += " -j"
3188 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003189 assert "Command not found:" not in output, output
3190 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003191 return output
Jon Hallbe379602015-03-24 13:39:32 -07003192 # FIXME: look at specific exceptions/Errors
3193 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003194 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003195 return None
3196 except TypeError:
3197 main.log.exception( self.name + ": Object not as expected" )
3198 return None
3199 except pexpect.EOF:
3200 main.log.error( self.name + ": EOF exception found" )
3201 main.log.error( self.name + ": " + self.handle.before )
3202 main.cleanup()
3203 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003204 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003205 main.log.exception( self.name + ": Uncaught exception!" )
3206 main.cleanup()
3207 main.exit()
3208
Jon Hall146f1522015-03-24 15:33:24 -07003209 def appStatus( self, appName ):
3210 """
3211 Uses the onos:apps cli command to return the status of an application.
3212 Returns:
3213 "ACTIVE" - If app is installed and activated
3214 "INSTALLED" - If app is installed and deactivated
3215 "UNINSTALLED" - If app is not installed
3216 None - on error
3217 """
Jon Hall146f1522015-03-24 15:33:24 -07003218 try:
3219 if not isinstance( appName, types.StringType ):
3220 main.log.error( self.name + ".appStatus(): appName must be" +
3221 " a string" )
3222 return None
3223 output = self.apps( jsonFormat=True )
3224 appsJson = json.loads( output )
3225 state = None
3226 for app in appsJson:
3227 if appName == app.get('name'):
3228 state = app.get('state')
3229 break
3230 if state == "ACTIVE" or state == "INSTALLED":
3231 return state
3232 elif state is None:
3233 return "UNINSTALLED"
3234 elif state:
3235 main.log.error( "Unexpected state from 'onos:apps': " +
3236 str( state ) )
3237 return state
Jon Hallc6793552016-01-19 14:18:37 -08003238 except ( TypeError, ValueError ):
3239 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003240 return None
3241 except pexpect.EOF:
3242 main.log.error( self.name + ": EOF exception found" )
3243 main.log.error( self.name + ": " + self.handle.before )
3244 main.cleanup()
3245 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003246 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003247 main.log.exception( self.name + ": Uncaught exception!" )
3248 main.cleanup()
3249 main.exit()
3250
Jon Hallbe379602015-03-24 13:39:32 -07003251 def app( self, appName, option ):
3252 """
3253 Interacts with the app command for ONOS. This command manages
3254 application inventory.
3255 """
Jon Hallbe379602015-03-24 13:39:32 -07003256 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003257 # Validate argument types
3258 valid = True
3259 if not isinstance( appName, types.StringType ):
3260 main.log.error( self.name + ".app(): appName must be a " +
3261 "string" )
3262 valid = False
3263 if not isinstance( option, types.StringType ):
3264 main.log.error( self.name + ".app(): option must be a string" )
3265 valid = False
3266 if not valid:
3267 return main.FALSE
3268 # Validate Option
3269 option = option.lower()
3270 # NOTE: Install may become a valid option
3271 if option == "activate":
3272 pass
3273 elif option == "deactivate":
3274 pass
3275 elif option == "uninstall":
3276 pass
3277 else:
3278 # Invalid option
3279 main.log.error( "The ONOS app command argument only takes " +
3280 "the values: (activate|deactivate|uninstall)" +
3281 "; was given '" + option + "'")
3282 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003283 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003284 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003285 if "Error executing command" in output:
3286 main.log.error( "Error in processing onos:app command: " +
3287 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003288 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003289 elif "No such application" in output:
3290 main.log.error( "The application '" + appName +
3291 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003292 return main.FALSE
3293 elif "Command not found:" in output:
3294 main.log.error( "Error in processing onos:app command: " +
3295 str( output ) )
3296 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003297 elif "Unsupported command:" in output:
3298 main.log.error( "Incorrect command given to 'app': " +
3299 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003300 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003301 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003302 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003303 return main.TRUE
3304 except TypeError:
3305 main.log.exception( self.name + ": Object not as expected" )
3306 return main.ERROR
3307 except pexpect.EOF:
3308 main.log.error( self.name + ": EOF exception found" )
3309 main.log.error( self.name + ": " + self.handle.before )
3310 main.cleanup()
3311 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003312 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003313 main.log.exception( self.name + ": Uncaught exception!" )
3314 main.cleanup()
3315 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003316
Jon Hallbd16b922015-03-26 17:53:15 -07003317 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003318 """
3319 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003320 appName is the hierarchical app name, not the feature name
3321 If check is True, method will check the status of the app after the
3322 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003323 Returns main.TRUE if the command was successfully sent
3324 main.FALSE if the cli responded with an error or given
3325 incorrect input
3326 """
3327 try:
3328 if not isinstance( appName, types.StringType ):
3329 main.log.error( self.name + ".activateApp(): appName must be" +
3330 " a string" )
3331 return main.FALSE
3332 status = self.appStatus( appName )
3333 if status == "INSTALLED":
3334 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003335 if check and response == main.TRUE:
3336 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003337 status = self.appStatus( appName )
3338 if status == "ACTIVE":
3339 return main.TRUE
3340 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003341 main.log.debug( "The state of application " +
3342 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003343 time.sleep( 1 )
3344 return main.FALSE
3345 else: # not 'check' or command didn't succeed
3346 return response
Jon Hall146f1522015-03-24 15:33:24 -07003347 elif status == "ACTIVE":
3348 return main.TRUE
3349 elif status == "UNINSTALLED":
3350 main.log.error( self.name + ": Tried to activate the " +
3351 "application '" + appName + "' which is not " +
3352 "installed." )
3353 else:
3354 main.log.error( "Unexpected return value from appStatus: " +
3355 str( status ) )
3356 return main.ERROR
3357 except TypeError:
3358 main.log.exception( self.name + ": Object not as expected" )
3359 return main.ERROR
3360 except pexpect.EOF:
3361 main.log.error( self.name + ": EOF exception found" )
3362 main.log.error( self.name + ": " + self.handle.before )
3363 main.cleanup()
3364 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003365 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003366 main.log.exception( self.name + ": Uncaught exception!" )
3367 main.cleanup()
3368 main.exit()
3369
Jon Hallbd16b922015-03-26 17:53:15 -07003370 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003371 """
3372 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003373 appName is the hierarchical app name, not the feature name
3374 If check is True, method will check the status of the app after the
3375 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003376 Returns main.TRUE if the command was successfully sent
3377 main.FALSE if the cli responded with an error or given
3378 incorrect input
3379 """
3380 try:
3381 if not isinstance( appName, types.StringType ):
3382 main.log.error( self.name + ".deactivateApp(): appName must " +
3383 "be a string" )
3384 return main.FALSE
3385 status = self.appStatus( appName )
3386 if status == "INSTALLED":
3387 return main.TRUE
3388 elif status == "ACTIVE":
3389 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003390 if check and response == main.TRUE:
3391 for i in range(10): # try 10 times then give up
3392 status = self.appStatus( appName )
3393 if status == "INSTALLED":
3394 return main.TRUE
3395 else:
3396 time.sleep( 1 )
3397 return main.FALSE
3398 else: # not check or command didn't succeed
3399 return response
Jon Hall146f1522015-03-24 15:33:24 -07003400 elif status == "UNINSTALLED":
3401 main.log.warn( self.name + ": Tried to deactivate the " +
3402 "application '" + appName + "' which is not " +
3403 "installed." )
3404 return main.TRUE
3405 else:
3406 main.log.error( "Unexpected return value from appStatus: " +
3407 str( status ) )
3408 return main.ERROR
3409 except TypeError:
3410 main.log.exception( self.name + ": Object not as expected" )
3411 return main.ERROR
3412 except pexpect.EOF:
3413 main.log.error( self.name + ": EOF exception found" )
3414 main.log.error( self.name + ": " + self.handle.before )
3415 main.cleanup()
3416 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003417 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003418 main.log.exception( self.name + ": Uncaught exception!" )
3419 main.cleanup()
3420 main.exit()
3421
Jon Hallbd16b922015-03-26 17:53:15 -07003422 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003423 """
3424 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003425 appName is the hierarchical app name, not the feature name
3426 If check is True, method will check the status of the app after the
3427 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003428 Returns main.TRUE if the command was successfully sent
3429 main.FALSE if the cli responded with an error or given
3430 incorrect input
3431 """
3432 # TODO: check with Thomas about the state machine for apps
3433 try:
3434 if not isinstance( appName, types.StringType ):
3435 main.log.error( self.name + ".uninstallApp(): appName must " +
3436 "be a string" )
3437 return main.FALSE
3438 status = self.appStatus( appName )
3439 if status == "INSTALLED":
3440 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003441 if check and response == main.TRUE:
3442 for i in range(10): # try 10 times then give up
3443 status = self.appStatus( appName )
3444 if status == "UNINSTALLED":
3445 return main.TRUE
3446 else:
3447 time.sleep( 1 )
3448 return main.FALSE
3449 else: # not check or command didn't succeed
3450 return response
Jon Hall146f1522015-03-24 15:33:24 -07003451 elif status == "ACTIVE":
3452 main.log.warn( self.name + ": Tried to uninstall the " +
3453 "application '" + appName + "' which is " +
3454 "currently active." )
3455 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003456 if check and response == main.TRUE:
3457 for i in range(10): # try 10 times then give up
3458 status = self.appStatus( appName )
3459 if status == "UNINSTALLED":
3460 return main.TRUE
3461 else:
3462 time.sleep( 1 )
3463 return main.FALSE
3464 else: # not check or command didn't succeed
3465 return response
Jon Hall146f1522015-03-24 15:33:24 -07003466 elif status == "UNINSTALLED":
3467 return main.TRUE
3468 else:
3469 main.log.error( "Unexpected return value from appStatus: " +
3470 str( status ) )
3471 return main.ERROR
3472 except TypeError:
3473 main.log.exception( self.name + ": Object not as expected" )
3474 return main.ERROR
3475 except pexpect.EOF:
3476 main.log.error( self.name + ": EOF exception found" )
3477 main.log.error( self.name + ": " + self.handle.before )
3478 main.cleanup()
3479 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003480 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003481 main.log.exception( self.name + ": Uncaught exception!" )
3482 main.cleanup()
3483 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003484
3485 def appIDs( self, jsonFormat=True ):
3486 """
3487 Show the mappings between app id and app names given by the 'app-ids'
3488 cli command
3489 """
3490 try:
3491 cmdStr = "app-ids"
3492 if jsonFormat:
3493 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003494 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003495 assert "Command not found:" not in output, output
3496 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003497 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003498 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003499 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003500 return None
3501 except TypeError:
3502 main.log.exception( self.name + ": Object not as expected" )
3503 return None
3504 except pexpect.EOF:
3505 main.log.error( self.name + ": EOF exception found" )
3506 main.log.error( self.name + ": " + self.handle.before )
3507 main.cleanup()
3508 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003509 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003510 main.log.exception( self.name + ": Uncaught exception!" )
3511 main.cleanup()
3512 main.exit()
3513
3514 def appToIDCheck( self ):
3515 """
3516 This method will check that each application's ID listed in 'apps' is
3517 the same as the ID listed in 'app-ids'. The check will also check that
3518 there are no duplicate IDs issued. Note that an app ID should be
3519 a globaly unique numerical identifier for app/app-like features. Once
3520 an ID is registered, the ID is never freed up so that if an app is
3521 reinstalled it will have the same ID.
3522
3523 Returns: main.TRUE if the check passes and
3524 main.FALSE if the check fails or
3525 main.ERROR if there is some error in processing the test
3526 """
3527 try:
Jon Hall390696c2015-05-05 17:13:41 -07003528 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003529 rawJson = self.appIDs( jsonFormat=True )
3530 if rawJson:
3531 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003532 else:
Jon Hallc6793552016-01-19 14:18:37 -08003533 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003534 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003535 rawJson = self.apps( jsonFormat=True )
3536 if rawJson:
3537 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003538 else:
Jon Hallc6793552016-01-19 14:18:37 -08003539 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003540 bail = True
3541 if bail:
3542 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003543 result = main.TRUE
3544 for app in apps:
3545 appID = app.get( 'id' )
3546 if appID is None:
3547 main.log.error( "Error parsing app: " + str( app ) )
3548 result = main.FALSE
3549 appName = app.get( 'name' )
3550 if appName is None:
3551 main.log.error( "Error parsing app: " + str( app ) )
3552 result = main.FALSE
3553 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003554 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003555 # main.log.debug( "Comparing " + str( app ) + " to " +
3556 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003557 if not current: # if ids doesn't have this id
3558 result = main.FALSE
3559 main.log.error( "'app-ids' does not have the ID for " +
3560 str( appName ) + " that apps does." )
3561 elif len( current ) > 1:
3562 # there is more than one app with this ID
3563 result = main.FALSE
3564 # We will log this later in the method
3565 elif not current[0][ 'name' ] == appName:
3566 currentName = current[0][ 'name' ]
3567 result = main.FALSE
3568 main.log.error( "'app-ids' has " + str( currentName ) +
3569 " registered under id:" + str( appID ) +
3570 " but 'apps' has " + str( appName ) )
3571 else:
3572 pass # id and name match!
3573 # now make sure that app-ids has no duplicates
3574 idsList = []
3575 namesList = []
3576 for item in ids:
3577 idsList.append( item[ 'id' ] )
3578 namesList.append( item[ 'name' ] )
3579 if len( idsList ) != len( set( idsList ) ) or\
3580 len( namesList ) != len( set( namesList ) ):
3581 main.log.error( "'app-ids' has some duplicate entries: \n"
3582 + json.dumps( ids,
3583 sort_keys=True,
3584 indent=4,
3585 separators=( ',', ': ' ) ) )
3586 result = main.FALSE
3587 return result
Jon Hallc6793552016-01-19 14:18:37 -08003588 except ( TypeError, ValueError ):
3589 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003590 return main.ERROR
3591 except pexpect.EOF:
3592 main.log.error( self.name + ": EOF exception found" )
3593 main.log.error( self.name + ": " + self.handle.before )
3594 main.cleanup()
3595 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003596 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003597 main.log.exception( self.name + ": Uncaught exception!" )
3598 main.cleanup()
3599 main.exit()
3600
Jon Hallfb760a02015-04-13 15:35:03 -07003601 def getCfg( self, component=None, propName=None, short=False,
3602 jsonFormat=True ):
3603 """
3604 Get configuration settings from onos cli
3605 Optional arguments:
3606 component - Optionally only list configurations for a specific
3607 component. If None, all components with configurations
3608 are displayed. Case Sensitive string.
3609 propName - If component is specified, propName option will show
3610 only this specific configuration from that component.
3611 Case Sensitive string.
3612 jsonFormat - Returns output as json. Note that this will override
3613 the short option
3614 short - Short, less verbose, version of configurations.
3615 This is overridden by the json option
3616 returns:
3617 Output from cli as a string or None on error
3618 """
3619 try:
3620 baseStr = "cfg"
3621 cmdStr = " get"
3622 componentStr = ""
3623 if component:
3624 componentStr += " " + component
3625 if propName:
3626 componentStr += " " + propName
3627 if jsonFormat:
3628 baseStr += " -j"
3629 elif short:
3630 baseStr += " -s"
3631 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003632 assert "Command not found:" not in output, output
3633 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003634 return output
3635 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003636 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003637 return None
3638 except TypeError:
3639 main.log.exception( self.name + ": Object not as expected" )
3640 return None
3641 except pexpect.EOF:
3642 main.log.error( self.name + ": EOF exception found" )
3643 main.log.error( self.name + ": " + self.handle.before )
3644 main.cleanup()
3645 main.exit()
3646 except Exception:
3647 main.log.exception( self.name + ": Uncaught exception!" )
3648 main.cleanup()
3649 main.exit()
3650
3651 def setCfg( self, component, propName, value=None, check=True ):
3652 """
3653 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003654 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003655 component - The case sensitive name of the component whose
3656 property is to be set
3657 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003658 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003659 value - The value to set the property to. If None, will unset the
3660 property and revert it to it's default value(if applicable)
3661 check - Boolean, Check whether the option was successfully set this
3662 only applies when a value is given.
3663 returns:
3664 main.TRUE on success or main.FALSE on failure. If check is False,
3665 will return main.TRUE unless there is an error
3666 """
3667 try:
3668 baseStr = "cfg"
3669 cmdStr = " set " + str( component ) + " " + str( propName )
3670 if value is not None:
3671 cmdStr += " " + str( value )
3672 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003673 assert "Command not found:" not in output, output
3674 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003675 if value and check:
3676 results = self.getCfg( component=str( component ),
3677 propName=str( propName ),
3678 jsonFormat=True )
3679 # Check if current value is what we just set
3680 try:
3681 jsonOutput = json.loads( results )
3682 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003683 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003684 main.log.exception( "Error parsing cfg output" )
3685 main.log.error( "output:" + repr( results ) )
3686 return main.FALSE
3687 if current == str( value ):
3688 return main.TRUE
3689 return main.FALSE
3690 return main.TRUE
3691 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003692 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003693 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003694 except ( TypeError, ValueError ):
3695 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003696 return main.FALSE
3697 except pexpect.EOF:
3698 main.log.error( self.name + ": EOF exception found" )
3699 main.log.error( self.name + ": " + self.handle.before )
3700 main.cleanup()
3701 main.exit()
3702 except Exception:
3703 main.log.exception( self.name + ": Uncaught exception!" )
3704 main.cleanup()
3705 main.exit()
3706
Jon Hall390696c2015-05-05 17:13:41 -07003707 def setTestAdd( self, setName, values ):
3708 """
3709 CLI command to add elements to a distributed set.
3710 Arguments:
3711 setName - The name of the set to add to.
3712 values - The value(s) to add to the set, space seperated.
3713 Example usages:
3714 setTestAdd( "set1", "a b c" )
3715 setTestAdd( "set2", "1" )
3716 returns:
3717 main.TRUE on success OR
3718 main.FALSE if elements were already in the set OR
3719 main.ERROR on error
3720 """
3721 try:
3722 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3723 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003724 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003725 try:
3726 # TODO: Maybe make this less hardcoded
3727 # ConsistentMap Exceptions
3728 assert "org.onosproject.store.service" not in output
3729 # Node not leader
3730 assert "java.lang.IllegalStateException" not in output
3731 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003732 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003733 "command: " + str( output ) )
3734 retryTime = 30 # Conservative time, given by Madan
3735 main.log.info( "Waiting " + str( retryTime ) +
3736 "seconds before retrying." )
3737 time.sleep( retryTime ) # Due to change in mastership
3738 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003739 assert "Error executing command" not in output
3740 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3741 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3742 main.log.info( self.name + ": " + output )
3743 if re.search( positiveMatch, output):
3744 return main.TRUE
3745 elif re.search( negativeMatch, output):
3746 return main.FALSE
3747 else:
3748 main.log.error( self.name + ": setTestAdd did not" +
3749 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003750 main.log.debug( self.name + " actual: " + repr( output ) )
3751 return main.ERROR
3752 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003753 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003754 return main.ERROR
3755 except TypeError:
3756 main.log.exception( self.name + ": Object not as expected" )
3757 return main.ERROR
3758 except pexpect.EOF:
3759 main.log.error( self.name + ": EOF exception found" )
3760 main.log.error( self.name + ": " + self.handle.before )
3761 main.cleanup()
3762 main.exit()
3763 except Exception:
3764 main.log.exception( self.name + ": Uncaught exception!" )
3765 main.cleanup()
3766 main.exit()
3767
3768 def setTestRemove( self, setName, values, clear=False, retain=False ):
3769 """
3770 CLI command to remove elements from a distributed set.
3771 Required arguments:
3772 setName - The name of the set to remove from.
3773 values - The value(s) to remove from the set, space seperated.
3774 Optional arguments:
3775 clear - Clear all elements from the set
3776 retain - Retain only the given values. (intersection of the
3777 original set and the given set)
3778 returns:
3779 main.TRUE on success OR
3780 main.FALSE if the set was not changed OR
3781 main.ERROR on error
3782 """
3783 try:
3784 cmdStr = "set-test-remove "
3785 if clear:
3786 cmdStr += "-c " + str( setName )
3787 elif retain:
3788 cmdStr += "-r " + str( setName ) + " " + str( values )
3789 else:
3790 cmdStr += str( setName ) + " " + str( values )
3791 output = self.sendline( cmdStr )
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 Hallc6793552016-01-19 14:18:37 -08003806 assert "Command not found:" not in output, output
3807 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003808 main.log.info( self.name + ": " + output )
3809 if clear:
3810 pattern = "Set " + str( setName ) + " cleared"
3811 if re.search( pattern, output ):
3812 return main.TRUE
3813 elif retain:
3814 positivePattern = str( setName ) + " was pruned to contain " +\
3815 "only elements of set \[(.*)\]"
3816 negativePattern = str( setName ) + " was not changed by " +\
3817 "retaining only elements of the set " +\
3818 "\[(.*)\]"
3819 if re.search( positivePattern, output ):
3820 return main.TRUE
3821 elif re.search( negativePattern, output ):
3822 return main.FALSE
3823 else:
3824 positivePattern = "\[(.*)\] was removed from the set " +\
3825 str( setName )
3826 if ( len( values.split() ) == 1 ):
3827 negativePattern = "\[(.*)\] was not in set " +\
3828 str( setName )
3829 else:
3830 negativePattern = "No element of \[(.*)\] was in set " +\
3831 str( setName )
3832 if re.search( positivePattern, output ):
3833 return main.TRUE
3834 elif re.search( negativePattern, output ):
3835 return main.FALSE
3836 main.log.error( self.name + ": setTestRemove did not" +
3837 " match expected output" )
3838 main.log.debug( self.name + " expected: " + pattern )
3839 main.log.debug( self.name + " actual: " + repr( output ) )
3840 return main.ERROR
3841 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003842 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003843 return main.ERROR
3844 except TypeError:
3845 main.log.exception( self.name + ": Object not as expected" )
3846 return main.ERROR
3847 except pexpect.EOF:
3848 main.log.error( self.name + ": EOF exception found" )
3849 main.log.error( self.name + ": " + self.handle.before )
3850 main.cleanup()
3851 main.exit()
3852 except Exception:
3853 main.log.exception( self.name + ": Uncaught exception!" )
3854 main.cleanup()
3855 main.exit()
3856
3857 def setTestGet( self, setName, values="" ):
3858 """
3859 CLI command to get the elements in a distributed set.
3860 Required arguments:
3861 setName - The name of the set to remove from.
3862 Optional arguments:
3863 values - The value(s) to check if in the set, space seperated.
3864 returns:
3865 main.ERROR on error OR
3866 A list of elements in the set if no optional arguments are
3867 supplied OR
3868 A tuple containing the list then:
3869 main.FALSE if the given values are not in the set OR
3870 main.TRUE if the given values are in the set OR
3871 """
3872 try:
3873 values = str( values ).strip()
3874 setName = str( setName ).strip()
3875 length = len( values.split() )
3876 containsCheck = None
3877 # Patterns to match
3878 setPattern = "\[(.*)\]"
3879 pattern = "Items in set " + setName + ":\n" + setPattern
3880 containsTrue = "Set " + setName + " contains the value " + values
3881 containsFalse = "Set " + setName + " did not contain the value " +\
3882 values
3883 containsAllTrue = "Set " + setName + " contains the the subset " +\
3884 setPattern
3885 containsAllFalse = "Set " + setName + " did not contain the the" +\
3886 " subset " + setPattern
3887
3888 cmdStr = "set-test-get "
3889 cmdStr += setName + " " + values
3890 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003891 try:
3892 # TODO: Maybe make this less hardcoded
3893 # ConsistentMap Exceptions
3894 assert "org.onosproject.store.service" not in output
3895 # Node not leader
3896 assert "java.lang.IllegalStateException" not in output
3897 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003898 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003899 "command: " + str( output ) )
3900 retryTime = 30 # Conservative time, given by Madan
3901 main.log.info( "Waiting " + str( retryTime ) +
3902 "seconds before retrying." )
3903 time.sleep( retryTime ) # Due to change in mastership
3904 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003905 assert "Command not found:" not in output, output
3906 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003907 main.log.info( self.name + ": " + output )
3908
3909 if length == 0:
3910 match = re.search( pattern, output )
3911 else: # if given values
3912 if length == 1: # Contains output
3913 patternTrue = pattern + "\n" + containsTrue
3914 patternFalse = pattern + "\n" + containsFalse
3915 else: # ContainsAll output
3916 patternTrue = pattern + "\n" + containsAllTrue
3917 patternFalse = pattern + "\n" + containsAllFalse
3918 matchTrue = re.search( patternTrue, output )
3919 matchFalse = re.search( patternFalse, output )
3920 if matchTrue:
3921 containsCheck = main.TRUE
3922 match = matchTrue
3923 elif matchFalse:
3924 containsCheck = main.FALSE
3925 match = matchFalse
3926 else:
3927 main.log.error( self.name + " setTestGet did not match " +\
3928 "expected output" )
3929 main.log.debug( self.name + " expected: " + pattern )
3930 main.log.debug( self.name + " actual: " + repr( output ) )
3931 match = None
3932 if match:
3933 setMatch = match.group( 1 )
3934 if setMatch == '':
3935 setList = []
3936 else:
3937 setList = setMatch.split( ", " )
3938 if length > 0:
3939 return ( setList, containsCheck )
3940 else:
3941 return setList
3942 else: # no match
3943 main.log.error( self.name + ": setTestGet did not" +
3944 " match expected output" )
3945 main.log.debug( self.name + " expected: " + pattern )
3946 main.log.debug( self.name + " actual: " + repr( output ) )
3947 return main.ERROR
3948 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003949 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003950 return main.ERROR
3951 except TypeError:
3952 main.log.exception( self.name + ": Object not as expected" )
3953 return main.ERROR
3954 except pexpect.EOF:
3955 main.log.error( self.name + ": EOF exception found" )
3956 main.log.error( self.name + ": " + self.handle.before )
3957 main.cleanup()
3958 main.exit()
3959 except Exception:
3960 main.log.exception( self.name + ": Uncaught exception!" )
3961 main.cleanup()
3962 main.exit()
3963
3964 def setTestSize( self, setName ):
3965 """
3966 CLI command to get the elements in a distributed set.
3967 Required arguments:
3968 setName - The name of the set to remove from.
3969 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003970 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003971 None on error
3972 """
3973 try:
3974 # TODO: Should this check against the number of elements returned
3975 # and then return true/false based on that?
3976 setName = str( setName ).strip()
3977 # Patterns to match
3978 setPattern = "\[(.*)\]"
3979 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3980 setPattern
3981 cmdStr = "set-test-get -s "
3982 cmdStr += setName
3983 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003984 try:
3985 # TODO: Maybe make this less hardcoded
3986 # ConsistentMap Exceptions
3987 assert "org.onosproject.store.service" not in output
3988 # Node not leader
3989 assert "java.lang.IllegalStateException" not in output
3990 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003991 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003992 "command: " + str( output ) )
3993 retryTime = 30 # Conservative time, given by Madan
3994 main.log.info( "Waiting " + str( retryTime ) +
3995 "seconds before retrying." )
3996 time.sleep( retryTime ) # Due to change in mastership
3997 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003998 assert "Command not found:" not in output, output
3999 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004000 main.log.info( self.name + ": " + output )
4001 match = re.search( pattern, output )
4002 if match:
4003 setSize = int( match.group( 1 ) )
4004 setMatch = match.group( 2 )
4005 if len( setMatch.split() ) == setSize:
4006 main.log.info( "The size returned by " + self.name +
4007 " matches the number of elements in " +
4008 "the returned set" )
4009 else:
4010 main.log.error( "The size returned by " + self.name +
4011 " does not match the number of " +
4012 "elements in the returned set." )
4013 return setSize
4014 else: # no match
4015 main.log.error( self.name + ": setTestGet did not" +
4016 " match expected output" )
4017 main.log.debug( self.name + " expected: " + pattern )
4018 main.log.debug( self.name + " actual: " + repr( output ) )
4019 return None
4020 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004021 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004022 return None
Jon Hall390696c2015-05-05 17:13:41 -07004023 except TypeError:
4024 main.log.exception( self.name + ": Object not as expected" )
4025 return None
4026 except pexpect.EOF:
4027 main.log.error( self.name + ": EOF exception found" )
4028 main.log.error( self.name + ": " + self.handle.before )
4029 main.cleanup()
4030 main.exit()
4031 except Exception:
4032 main.log.exception( self.name + ": Uncaught exception!" )
4033 main.cleanup()
4034 main.exit()
4035
Jon Hall80daded2015-05-27 16:07:00 -07004036 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004037 """
4038 Command to list the various counters in the system.
4039 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004040 if jsonFormat, a string of the json object returned by the cli
4041 command
4042 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004043 None on error
4044 """
Jon Hall390696c2015-05-05 17:13:41 -07004045 try:
4046 counters = {}
4047 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004048 if jsonFormat:
4049 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004050 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004051 assert "Command not found:" not in output, output
4052 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004053 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004054 return output
Jon Hall390696c2015-05-05 17:13:41 -07004055 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004056 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004057 return None
Jon Hall390696c2015-05-05 17:13:41 -07004058 except TypeError:
4059 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004060 return None
Jon Hall390696c2015-05-05 17:13:41 -07004061 except pexpect.EOF:
4062 main.log.error( self.name + ": EOF exception found" )
4063 main.log.error( self.name + ": " + self.handle.before )
4064 main.cleanup()
4065 main.exit()
4066 except Exception:
4067 main.log.exception( self.name + ": Uncaught exception!" )
4068 main.cleanup()
4069 main.exit()
4070
Jon Hall935db192016-04-19 00:22:04 -07004071 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004072 """
Jon Halle1a3b752015-07-22 13:02:46 -07004073 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004074 Required arguments:
4075 counter - The name of the counter to increment.
4076 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004077 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004078 returns:
4079 integer value of the counter or
4080 None on Error
4081 """
4082 try:
4083 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004084 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004085 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004086 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004087 if delta != 1:
4088 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004089 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004090 try:
4091 # TODO: Maybe make this less hardcoded
4092 # ConsistentMap Exceptions
4093 assert "org.onosproject.store.service" not in output
4094 # Node not leader
4095 assert "java.lang.IllegalStateException" not in output
4096 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004097 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004098 "command: " + str( output ) )
4099 retryTime = 30 # Conservative time, given by Madan
4100 main.log.info( "Waiting " + str( retryTime ) +
4101 "seconds before retrying." )
4102 time.sleep( retryTime ) # Due to change in mastership
4103 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004104 assert "Command not found:" not in output, output
4105 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004106 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004107 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004108 match = re.search( pattern, output )
4109 if match:
4110 return int( match.group( 1 ) )
4111 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004112 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004113 " match expected output." )
4114 main.log.debug( self.name + " expected: " + pattern )
4115 main.log.debug( self.name + " actual: " + repr( output ) )
4116 return None
4117 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004118 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004119 return None
4120 except TypeError:
4121 main.log.exception( self.name + ": Object not as expected" )
4122 return None
4123 except pexpect.EOF:
4124 main.log.error( self.name + ": EOF exception found" )
4125 main.log.error( self.name + ": " + self.handle.before )
4126 main.cleanup()
4127 main.exit()
4128 except Exception:
4129 main.log.exception( self.name + ": Uncaught exception!" )
4130 main.cleanup()
4131 main.exit()
4132
Jon Hall935db192016-04-19 00:22:04 -07004133 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004134 """
4135 CLI command to get a distributed counter then add a delta to it.
4136 Required arguments:
4137 counter - The name of the counter to increment.
4138 Optional arguments:
4139 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004140 returns:
4141 integer value of the counter or
4142 None on Error
4143 """
4144 try:
4145 counter = str( counter )
4146 delta = int( delta )
4147 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004148 cmdStr += counter
4149 if delta != 1:
4150 cmdStr += " " + str( delta )
4151 output = self.sendline( cmdStr )
4152 try:
4153 # TODO: Maybe make this less hardcoded
4154 # ConsistentMap Exceptions
4155 assert "org.onosproject.store.service" not in output
4156 # Node not leader
4157 assert "java.lang.IllegalStateException" not in output
4158 except AssertionError:
4159 main.log.error( "Error in processing '" + cmdStr + "' " +
4160 "command: " + str( output ) )
4161 retryTime = 30 # Conservative time, given by Madan
4162 main.log.info( "Waiting " + str( retryTime ) +
4163 "seconds before retrying." )
4164 time.sleep( retryTime ) # Due to change in mastership
4165 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004166 assert "Command not found:" not in output, output
4167 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004168 main.log.info( self.name + ": " + output )
4169 pattern = counter + " was updated to (-?\d+)"
4170 match = re.search( pattern, output )
4171 if match:
4172 return int( match.group( 1 ) )
4173 else:
4174 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4175 " match expected output." )
4176 main.log.debug( self.name + " expected: " + pattern )
4177 main.log.debug( self.name + " actual: " + repr( output ) )
4178 return None
4179 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004180 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004181 return None
4182 except TypeError:
4183 main.log.exception( self.name + ": Object not as expected" )
4184 return None
4185 except pexpect.EOF:
4186 main.log.error( self.name + ": EOF exception found" )
4187 main.log.error( self.name + ": " + self.handle.before )
4188 main.cleanup()
4189 main.exit()
4190 except Exception:
4191 main.log.exception( self.name + ": Uncaught exception!" )
4192 main.cleanup()
4193 main.exit()
4194
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004195 def summary( self, jsonFormat=True ):
4196 """
4197 Description: Execute summary command in onos
4198 Returns: json object ( summary -j ), returns main.FALSE if there is
4199 no output
4200
4201 """
4202 try:
4203 cmdStr = "summary"
4204 if jsonFormat:
4205 cmdStr += " -j"
4206 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004207 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004208 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004209 if not handle:
4210 main.log.error( self.name + ": There is no output in " +
4211 "summary command" )
4212 return main.FALSE
4213 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004214 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004215 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004216 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004217 except TypeError:
4218 main.log.exception( self.name + ": Object not as expected" )
4219 return None
4220 except pexpect.EOF:
4221 main.log.error( self.name + ": EOF exception found" )
4222 main.log.error( self.name + ": " + self.handle.before )
4223 main.cleanup()
4224 main.exit()
4225 except Exception:
4226 main.log.exception( self.name + ": Uncaught exception!" )
4227 main.cleanup()
4228 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004229
Jon Hall935db192016-04-19 00:22:04 -07004230 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004231 """
4232 CLI command to get the value of a key in a consistent map using
4233 transactions. This a test function and can only get keys from the
4234 test map hard coded into the cli command
4235 Required arguments:
4236 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004237 returns:
4238 The string value of the key or
4239 None on Error
4240 """
4241 try:
4242 keyName = str( keyName )
4243 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004244 cmdStr += keyName
4245 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004246 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004247 try:
4248 # TODO: Maybe make this less hardcoded
4249 # ConsistentMap Exceptions
4250 assert "org.onosproject.store.service" not in output
4251 # Node not leader
4252 assert "java.lang.IllegalStateException" not in output
4253 except AssertionError:
4254 main.log.error( "Error in processing '" + cmdStr + "' " +
4255 "command: " + str( output ) )
4256 return None
4257 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4258 if "Key " + keyName + " not found." in output:
4259 return None
4260 else:
4261 match = re.search( pattern, output )
4262 if match:
4263 return match.groupdict()[ 'value' ]
4264 else:
4265 main.log.error( self.name + ": transactionlMapGet did not" +
4266 " match expected output." )
4267 main.log.debug( self.name + " expected: " + pattern )
4268 main.log.debug( self.name + " actual: " + repr( output ) )
4269 return None
Jon Hallc6793552016-01-19 14:18:37 -08004270 except AssertionError:
4271 main.log.exception( "" )
4272 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004273 except TypeError:
4274 main.log.exception( self.name + ": Object not as expected" )
4275 return None
4276 except pexpect.EOF:
4277 main.log.error( self.name + ": EOF exception found" )
4278 main.log.error( self.name + ": " + self.handle.before )
4279 main.cleanup()
4280 main.exit()
4281 except Exception:
4282 main.log.exception( self.name + ": Uncaught exception!" )
4283 main.cleanup()
4284 main.exit()
4285
Jon Hall935db192016-04-19 00:22:04 -07004286 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004287 """
4288 CLI command to put a value into 'numKeys' number of keys in a
4289 consistent map using transactions. This a test function and can only
4290 put into keys named 'Key#' of the test map hard coded into the cli command
4291 Required arguments:
4292 numKeys - Number of keys to add the value to
4293 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004294 returns:
4295 A dictionary whose keys are the name of the keys put into the map
4296 and the values of the keys are dictionaries whose key-values are
4297 'value': value put into map and optionaly
4298 'oldValue': Previous value in the key or
4299 None on Error
4300
4301 Example output
4302 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4303 'Key2': {'value': 'Testing'} }
4304 """
4305 try:
4306 numKeys = str( numKeys )
4307 value = str( value )
4308 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004309 cmdStr += numKeys + " " + value
4310 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004311 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004312 try:
4313 # TODO: Maybe make this less hardcoded
4314 # ConsistentMap Exceptions
4315 assert "org.onosproject.store.service" not in output
4316 # Node not leader
4317 assert "java.lang.IllegalStateException" not in output
4318 except AssertionError:
4319 main.log.error( "Error in processing '" + cmdStr + "' " +
4320 "command: " + str( output ) )
4321 return None
4322 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4323 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4324 results = {}
4325 for line in output.splitlines():
4326 new = re.search( newPattern, line )
4327 updated = re.search( updatedPattern, line )
4328 if new:
4329 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4330 elif updated:
4331 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004332 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004333 else:
4334 main.log.error( self.name + ": transactionlMapGet did not" +
4335 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004336 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4337 newPattern,
4338 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004339 main.log.debug( self.name + " actual: " + repr( output ) )
4340 return results
Jon Hallc6793552016-01-19 14:18:37 -08004341 except AssertionError:
4342 main.log.exception( "" )
4343 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004344 except TypeError:
4345 main.log.exception( self.name + ": Object not as expected" )
4346 return None
4347 except pexpect.EOF:
4348 main.log.error( self.name + ": EOF exception found" )
4349 main.log.error( self.name + ": " + self.handle.before )
4350 main.cleanup()
4351 main.exit()
4352 except Exception:
4353 main.log.exception( self.name + ": Uncaught exception!" )
4354 main.cleanup()
4355 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004356
acsmarsdaea66c2015-09-03 11:44:06 -07004357 def maps( self, jsonFormat=True ):
4358 """
4359 Description: Returns result of onos:maps
4360 Optional:
4361 * jsonFormat: enable json formatting of output
4362 """
4363 try:
4364 cmdStr = "maps"
4365 if jsonFormat:
4366 cmdStr += " -j"
4367 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004368 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004369 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004370 except AssertionError:
4371 main.log.exception( "" )
4372 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004373 except TypeError:
4374 main.log.exception( self.name + ": Object not as expected" )
4375 return None
4376 except pexpect.EOF:
4377 main.log.error( self.name + ": EOF exception found" )
4378 main.log.error( self.name + ": " + self.handle.before )
4379 main.cleanup()
4380 main.exit()
4381 except Exception:
4382 main.log.exception( self.name + ": Uncaught exception!" )
4383 main.cleanup()
4384 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004385
4386 def getSwController( self, uri, jsonFormat=True ):
4387 """
4388 Descrition: Gets the controller information from the device
4389 """
4390 try:
4391 cmd = "device-controllers "
4392 if jsonFormat:
4393 cmd += "-j "
4394 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004395 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004396 return response
Jon Hallc6793552016-01-19 14:18:37 -08004397 except AssertionError:
4398 main.log.exception( "" )
4399 return None
GlennRC050596c2015-11-18 17:06:41 -08004400 except TypeError:
4401 main.log.exception( self.name + ": Object not as expected" )
4402 return None
4403 except pexpect.EOF:
4404 main.log.error( self.name + ": EOF exception found" )
4405 main.log.error( self.name + ": " + self.handle.before )
4406 main.cleanup()
4407 main.exit()
4408 except Exception:
4409 main.log.exception( self.name + ": Uncaught exception!" )
4410 main.cleanup()
4411 main.exit()
4412
4413 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4414 """
4415 Descrition: sets the controller(s) for the specified device
4416
4417 Parameters:
4418 Required: uri - String: The uri of the device(switch).
4419 ip - String or List: The ip address of the controller.
4420 This parameter can be formed in a couple of different ways.
4421 VALID:
4422 10.0.0.1 - just the ip address
4423 tcp:10.0.0.1 - the protocol and the ip address
4424 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4425 so that you can add controllers with different
4426 protocols and ports
4427 INVALID:
4428 10.0.0.1:6653 - this is not supported by ONOS
4429
4430 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4431 port - The port number.
4432 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4433
4434 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4435 """
4436 try:
4437 cmd = "device-setcontrollers"
4438
4439 if jsonFormat:
4440 cmd += " -j"
4441 cmd += " " + uri
4442 if isinstance( ip, str ):
4443 ip = [ip]
4444 for item in ip:
4445 if ":" in item:
4446 sitem = item.split( ":" )
4447 if len(sitem) == 3:
4448 cmd += " " + item
4449 elif "." in sitem[1]:
4450 cmd += " {}:{}".format(item, port)
4451 else:
4452 main.log.error( "Malformed entry: " + item )
4453 raise TypeError
4454 else:
4455 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004456 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004457 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004458 if "Error" in response:
4459 main.log.error( response )
4460 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004461 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004462 except AssertionError:
4463 main.log.exception( "" )
4464 return None
GlennRC050596c2015-11-18 17:06:41 -08004465 except TypeError:
4466 main.log.exception( self.name + ": Object not as expected" )
4467 return main.FALSE
4468 except pexpect.EOF:
4469 main.log.error( self.name + ": EOF exception found" )
4470 main.log.error( self.name + ": " + self.handle.before )
4471 main.cleanup()
4472 main.exit()
4473 except Exception:
4474 main.log.exception( self.name + ": Uncaught exception!" )
4475 main.cleanup()
4476 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004477
4478 def removeDevice( self, device ):
4479 '''
4480 Description:
4481 Remove a device from ONOS by passing the uri of the device(s).
4482 Parameters:
4483 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4484 Returns:
4485 Returns main.FALSE if an exception is thrown or an error is present
4486 in the response. Otherwise, returns main.TRUE.
4487 NOTE:
4488 If a host cannot be removed, then this function will return main.FALSE
4489 '''
4490 try:
4491 if type( device ) is str:
4492 device = list( device )
4493
4494 for d in device:
4495 time.sleep( 1 )
4496 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004497 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004498 if "Error" in response:
4499 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4500 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004501 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004502 except AssertionError:
4503 main.log.exception( "" )
4504 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004505 except TypeError:
4506 main.log.exception( self.name + ": Object not as expected" )
4507 return main.FALSE
4508 except pexpect.EOF:
4509 main.log.error( self.name + ": EOF exception found" )
4510 main.log.error( self.name + ": " + self.handle.before )
4511 main.cleanup()
4512 main.exit()
4513 except Exception:
4514 main.log.exception( self.name + ": Uncaught exception!" )
4515 main.cleanup()
4516 main.exit()
4517
4518 def removeHost( self, host ):
4519 '''
4520 Description:
4521 Remove a host from ONOS by passing the id of the host(s)
4522 Parameters:
4523 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4524 Returns:
4525 Returns main.FALSE if an exception is thrown or an error is present
4526 in the response. Otherwise, returns main.TRUE.
4527 NOTE:
4528 If a host cannot be removed, then this function will return main.FALSE
4529 '''
4530 try:
4531 if type( host ) is str:
4532 host = list( host )
4533
4534 for h in host:
4535 time.sleep( 1 )
4536 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004537 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004538 if "Error" in response:
4539 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4540 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004541 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004542 except AssertionError:
4543 main.log.exception( "" )
4544 return None
GlennRC20fc6522015-12-23 23:26:57 -08004545 except TypeError:
4546 main.log.exception( self.name + ": Object not as expected" )
4547 return main.FALSE
4548 except pexpect.EOF:
4549 main.log.error( self.name + ": EOF exception found" )
4550 main.log.error( self.name + ": " + self.handle.before )
4551 main.cleanup()
4552 main.exit()
4553 except Exception:
4554 main.log.exception( self.name + ": Uncaught exception!" )
4555 main.cleanup()
4556 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004557
Jon Hallc6793552016-01-19 14:18:37 -08004558 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004559 '''
4560 Description:
4561 Bring link down or up in the null-provider.
4562 params:
4563 begin - (string) One end of a device or switch.
4564 end - (string) the other end of the device or switch
4565 returns:
4566 main.TRUE if no exceptions were thrown and no Errors are
4567 present in the resoponse. Otherwise, returns main.FALSE
4568 '''
4569 try:
Jon Hallc6793552016-01-19 14:18:37 -08004570 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004571 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004572 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004573 if "Error" in response or "Failure" in response:
4574 main.log.error( response )
4575 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004576 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004577 except AssertionError:
4578 main.log.exception( "" )
4579 return None
GlennRCed771242016-01-13 17:02:47 -08004580 except TypeError:
4581 main.log.exception( self.name + ": Object not as expected" )
4582 return main.FALSE
4583 except pexpect.EOF:
4584 main.log.error( self.name + ": EOF exception found" )
4585 main.log.error( self.name + ": " + self.handle.before )
4586 main.cleanup()
4587 main.exit()
4588 except Exception:
4589 main.log.exception( self.name + ": Uncaught exception!" )
4590 main.cleanup()
4591 main.exit()
4592