blob: 3c8b2ef5fbba0160b0503d365938bc2dd02741c3 [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 )
Jon Hallc6793552016-01-19 14:18:37 -0800931 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800932 try:
933 # 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
938 except AssertionError:
939 main.log.error( "Error in processing '" + cmdStr + "' " +
940 "command: " + str( handle ) )
941 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700942 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800943 except AssertionError:
944 main.log.exception( "" )
945 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800946 except TypeError:
947 main.log.exception( self.name + ": Object not as expected" )
948 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400952 main.cleanup()
953 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800954 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800955 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400956 main.cleanup()
957 main.exit()
958
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800960 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400961 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800962
Jon Hallefbd9792015-03-05 16:11:36 -0800963 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800964 partial mac address
965
Jon Hall42db6dc2014-10-24 19:03:48 -0400966 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800967 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400968 try:
kelvin8ec71442015-01-15 16:57:00 -0800969 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400970 return None
971 else:
972 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 rawHosts = self.hosts()
974 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800975 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800976 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800977 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 if not host:
979 pass
980 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400981 return host
982 return None
Jon Hallc6793552016-01-19 14:18:37 -0800983 except ( TypeError, ValueError ):
984 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800985 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400989 main.cleanup()
990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800992 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400993 main.cleanup()
994 main.exit()
995
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800997 """
998 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400999 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001000
andrewonlab3f0a4af2014-10-17 12:25:14 -04001001 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001002 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003 IMPORTANT:
1004 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001005 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001006 Furthermore, it assumes that value of VLAN is '-1'
1007 Description:
kelvin8ec71442015-01-15 16:57:00 -08001008 Converts mininet hosts ( h1, h2, h3... ) into
1009 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1010 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001011 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001015 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001016 hostHex = hex( int( host ) ).zfill( 12 )
1017 hostHex = str( hostHex ).replace( 'x', '0' )
1018 i = iter( str( hostHex ) )
1019 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1020 hostHex = hostHex + "/-1"
1021 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001022
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001024
Jon Halld4d4b372015-01-28 16:02:41 -08001025 except TypeError:
1026 main.log.exception( self.name + ": Object not as expected" )
1027 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001029 main.log.error( self.name + ": EOF exception found" )
1030 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001031 main.cleanup()
1032 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001034 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001035 main.cleanup()
1036 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001037
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001039 """
andrewonlabe6745342014-10-17 14:29:13 -04001040 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 * hostIdOne: ONOS host id for host1
1042 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001043 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001044 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001045 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001046 Returns:
1047 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001048 """
andrewonlabe6745342014-10-17 14:29:13 -04001049 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1051 " " + str( hostIdTwo )
1052 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001053 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001054 if re.search( "Error", handle ):
1055 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001056 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001057 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001058 else:
1059 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001060 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1061 match = re.search('id=0x([\da-f]+),', handle)
1062 if match:
1063 return match.group()[3:-1]
1064 else:
1065 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001066 main.log.debug( "Response from ONOS was: " +
1067 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001068 return None
Jon Hallc6793552016-01-19 14:18:37 -08001069 except AssertionError:
1070 main.log.exception( "" )
1071 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001072 except TypeError:
1073 main.log.exception( self.name + ": Object not as expected" )
1074 return None
andrewonlabe6745342014-10-17 14:29:13 -04001075 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001078 main.cleanup()
1079 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001080 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001081 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001082 main.cleanup()
1083 main.exit()
1084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001086 """
andrewonlab7b31d232014-10-24 13:31:47 -04001087 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 * ingressDevice: device id of ingress device
1089 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001090 Optional:
1091 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001092 Description:
1093 Adds an optical intent by specifying an ingress and egress device
1094 Returns:
1095 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001096 """
andrewonlab7b31d232014-10-24 13:31:47 -04001097 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1099 " " + str( egressDevice )
1100 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001101 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001102 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001103 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001104 main.log.error( "Error in adding Optical intent" )
1105 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001106 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001107 main.log.info( "Optical intent installed between " +
1108 str( ingressDevice ) + " and " +
1109 str( egressDevice ) )
1110 match = re.search('id=0x([\da-f]+),', handle)
1111 if match:
1112 return match.group()[3:-1]
1113 else:
1114 main.log.error( "Error, intent ID not found" )
1115 return None
Jon Hallc6793552016-01-19 14:18:37 -08001116 except AssertionError:
1117 main.log.exception( "" )
1118 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001119 except TypeError:
1120 main.log.exception( self.name + ": Object not as expected" )
1121 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001122 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001123 main.log.error( self.name + ": EOF exception found" )
1124 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001125 main.cleanup()
1126 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001127 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001128 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001129 main.cleanup()
1130 main.exit()
1131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001133 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 ingressDevice,
1135 egressDevice,
1136 portIngress="",
1137 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001138 ethType="",
1139 ethSrc="",
1140 ethDst="",
1141 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001143 ipProto="",
1144 ipSrc="",
1145 ipDst="",
1146 tcpSrc="",
1147 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001148 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001149 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001150 * ingressDevice: device id of ingress device
1151 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001152 Optional:
1153 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001154 * ethSrc: specify ethSrc ( i.e. src mac addr )
1155 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001156 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001158 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001159 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001160 * ipSrc: specify ip source address
1161 * ipDst: specify ip destination address
1162 * tcpSrc: specify tcp source port
1163 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001164 Description:
kelvin8ec71442015-01-15 16:57:00 -08001165 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001166 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001167 Returns:
1168 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001169
Jon Halle3f39ff2015-01-13 11:50:53 -08001170 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001171 options developers provide for point-to-point
1172 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001173 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001174 try:
kelvin8ec71442015-01-15 16:57:00 -08001175 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001176 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001178 and not ipProto and not ipSrc and not ipDst \
1179 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001180 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001181
andrewonlab289e4b72014-10-21 21:24:18 -04001182 else:
andrewonlab36af3822014-11-18 17:48:18 -05001183 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001184
andrewonlab0c0a6772014-10-22 12:31:18 -04001185 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001186 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001187 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001188 cmd += " --ethSrc " + str( ethSrc )
1189 if ethDst:
1190 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001191 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001192 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001194 cmd += " --lambda "
1195 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001196 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001197 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001198 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001199 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001200 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001201 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001202 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001203 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001204 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001205
kelvin8ec71442015-01-15 16:57:00 -08001206 # Check whether the user appended the port
1207 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if "/" in ingressDevice:
1209 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001210 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001212 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001213 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 # Would it make sense to throw an exception and exit
1215 # the test?
1216 return None
andrewonlab36af3822014-11-18 17:48:18 -05001217
kelvin8ec71442015-01-15 16:57:00 -08001218 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 str( ingressDevice ) + "/" +\
1220 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001221
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 if "/" in egressDevice:
1223 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001224 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001226 main.log.error( "You must specify the egress port" )
1227 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001228
kelvin8ec71442015-01-15 16:57:00 -08001229 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 str( egressDevice ) + "/" +\
1231 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001232
kelvin-onlab898a6c62015-01-16 14:13:53 -08001233 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001234 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001236 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001237 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001239 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 # TODO: print out all the options in this message?
1241 main.log.info( "Point-to-point intent installed between " +
1242 str( ingressDevice ) + " and " +
1243 str( egressDevice ) )
1244 match = re.search('id=0x([\da-f]+),', handle)
1245 if match:
1246 return match.group()[3:-1]
1247 else:
1248 main.log.error( "Error, intent ID not found" )
1249 return None
Jon Hallc6793552016-01-19 14:18:37 -08001250 except AssertionError:
1251 main.log.exception( "" )
1252 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001253 except TypeError:
1254 main.log.exception( self.name + ": Object not as expected" )
1255 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001256 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001257 main.log.error( self.name + ": EOF exception found" )
1258 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001259 main.cleanup()
1260 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001261 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001262 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001263 main.cleanup()
1264 main.exit()
1265
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001267 self,
shahshreyac2f97072015-03-19 17:04:29 -07001268 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001270 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001271 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 ethType="",
1273 ethSrc="",
1274 ethDst="",
1275 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001276 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001277 ipProto="",
1278 ipSrc="",
1279 ipDst="",
1280 tcpSrc="",
1281 tcpDst="",
1282 setEthSrc="",
1283 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001284 """
shahshreyad0c80432014-12-04 16:56:05 -08001285 Note:
shahshreya70622b12015-03-19 17:19:00 -07001286 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001287 is same. That is, all ingress devices include port numbers
1288 with a "/" or all ingress devices could specify device
1289 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001290 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001291 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001292 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001293 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001294 Optional:
1295 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001296 * ethSrc: specify ethSrc ( i.e. src mac addr )
1297 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001298 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001300 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001302 * ipSrc: specify ip source address
1303 * ipDst: specify ip destination address
1304 * tcpSrc: specify tcp source port
1305 * tcpDst: specify tcp destination port
1306 * setEthSrc: action to Rewrite Source MAC Address
1307 * setEthDst: action to Rewrite Destination MAC Address
1308 Description:
kelvin8ec71442015-01-15 16:57:00 -08001309 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001310 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001311 Returns:
1312 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001313
Jon Halle3f39ff2015-01-13 11:50:53 -08001314 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001315 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001316 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001317 """
shahshreyad0c80432014-12-04 16:56:05 -08001318 try:
kelvin8ec71442015-01-15 16:57:00 -08001319 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001320 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001322 and not ipProto and not ipSrc and not ipDst\
1323 and not tcpSrc and not tcpDst and not setEthSrc\
1324 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001325 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001326
1327 else:
1328 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001329
shahshreyad0c80432014-12-04 16:56:05 -08001330 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001331 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001332 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001333 cmd += " --ethSrc " + str( ethSrc )
1334 if ethDst:
1335 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001336 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001337 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001338 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001339 cmd += " --lambda "
1340 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001341 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001342 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001343 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001344 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001345 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001346 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001347 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001348 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001349 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001350 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001351 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001352 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001353 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001354
kelvin8ec71442015-01-15 16:57:00 -08001355 # Check whether the user appended the port
1356 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001357
1358 if portIngressList is None:
1359 for ingressDevice in ingressDeviceList:
1360 if "/" in ingressDevice:
1361 cmd += " " + str( ingressDevice )
1362 else:
1363 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001364 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001365 # TODO: perhaps more meaningful return
1366 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001367 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001368 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001369 for ingressDevice, portIngress in zip( ingressDeviceList,
1370 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001371 cmd += " " + \
1372 str( ingressDevice ) + "/" +\
1373 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001374 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001375 main.log.error( "Device list and port list does not " +
1376 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001377 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 if "/" in egressDevice:
1379 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001380 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001382 main.log.error( "You must specify " +
1383 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001384 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001385
kelvin8ec71442015-01-15 16:57:00 -08001386 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 str( egressDevice ) + "/" +\
1388 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001390 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001391 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001392 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001393 main.log.error( "Error in adding multipoint-to-singlepoint " +
1394 "intent" )
1395 return None
shahshreyad0c80432014-12-04 16:56:05 -08001396 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001397 match = re.search('id=0x([\da-f]+),', handle)
1398 if match:
1399 return match.group()[3:-1]
1400 else:
1401 main.log.error( "Error, intent ID not found" )
1402 return None
Jon Hallc6793552016-01-19 14:18:37 -08001403 except AssertionError:
1404 main.log.exception( "" )
1405 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001406 except TypeError:
1407 main.log.exception( self.name + ": Object not as expected" )
1408 return None
1409 except pexpect.EOF:
1410 main.log.error( self.name + ": EOF exception found" )
1411 main.log.error( self.name + ": " + self.handle.before )
1412 main.cleanup()
1413 main.exit()
1414 except Exception:
1415 main.log.exception( self.name + ": Uncaught exception!" )
1416 main.cleanup()
1417 main.exit()
1418
1419 def addSinglepointToMultipointIntent(
1420 self,
1421 ingressDevice,
1422 egressDeviceList,
1423 portIngress="",
1424 portEgressList=None,
1425 ethType="",
1426 ethSrc="",
1427 ethDst="",
1428 bandwidth="",
1429 lambdaAlloc=False,
1430 ipProto="",
1431 ipSrc="",
1432 ipDst="",
1433 tcpSrc="",
1434 tcpDst="",
1435 setEthSrc="",
1436 setEthDst="" ):
1437 """
1438 Note:
1439 This function assumes the format of all egress devices
1440 is same. That is, all egress devices include port numbers
1441 with a "/" or all egress devices could specify device
1442 ids and port numbers seperately.
1443 Required:
1444 * EgressDeviceList: List of device ids of egress device
1445 ( Atleast 2 eress devices required in the list )
1446 * ingressDevice: device id of ingress device
1447 Optional:
1448 * ethType: specify ethType
1449 * ethSrc: specify ethSrc ( i.e. src mac addr )
1450 * ethDst: specify ethDst ( i.e. dst mac addr )
1451 * bandwidth: specify bandwidth capacity of link
1452 * lambdaAlloc: if True, intent will allocate lambda
1453 for the specified intent
1454 * ipProto: specify ip protocol
1455 * ipSrc: specify ip source address
1456 * ipDst: specify ip destination address
1457 * tcpSrc: specify tcp source port
1458 * tcpDst: specify tcp destination port
1459 * setEthSrc: action to Rewrite Source MAC Address
1460 * setEthDst: action to Rewrite Destination MAC Address
1461 Description:
1462 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1463 specifying device id's and optional fields
1464 Returns:
1465 A string of the intent id or None on error
1466
1467 NOTE: This function may change depending on the
1468 options developers provide for singlepoint-to-multipoint
1469 intent via cli
1470 """
1471 try:
1472 # If there are no optional arguments
1473 if not ethType and not ethSrc and not ethDst\
1474 and not bandwidth and not lambdaAlloc\
1475 and not ipProto and not ipSrc and not ipDst\
1476 and not tcpSrc and not tcpDst and not setEthSrc\
1477 and not setEthDst:
1478 cmd = "add-single-to-multi-intent"
1479
1480 else:
1481 cmd = "add-single-to-multi-intent"
1482
1483 if ethType:
1484 cmd += " --ethType " + str( ethType )
1485 if ethSrc:
1486 cmd += " --ethSrc " + str( ethSrc )
1487 if ethDst:
1488 cmd += " --ethDst " + str( ethDst )
1489 if bandwidth:
1490 cmd += " --bandwidth " + str( bandwidth )
1491 if lambdaAlloc:
1492 cmd += " --lambda "
1493 if ipProto:
1494 cmd += " --ipProto " + str( ipProto )
1495 if ipSrc:
1496 cmd += " --ipSrc " + str( ipSrc )
1497 if ipDst:
1498 cmd += " --ipDst " + str( ipDst )
1499 if tcpSrc:
1500 cmd += " --tcpSrc " + str( tcpSrc )
1501 if tcpDst:
1502 cmd += " --tcpDst " + str( tcpDst )
1503 if setEthSrc:
1504 cmd += " --setEthSrc " + str( setEthSrc )
1505 if setEthDst:
1506 cmd += " --setEthDst " + str( setEthDst )
1507
1508 # Check whether the user appended the port
1509 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001510
kelvin-onlabb9408212015-04-01 13:34:04 -07001511 if "/" in ingressDevice:
1512 cmd += " " + str( ingressDevice )
1513 else:
1514 if not portIngress:
1515 main.log.error( "You must specify " +
1516 "the Ingress port" )
1517 return main.FALSE
1518
1519 cmd += " " +\
1520 str( ingressDevice ) + "/" +\
1521 str( portIngress )
1522
1523 if portEgressList is None:
1524 for egressDevice in egressDeviceList:
1525 if "/" in egressDevice:
1526 cmd += " " + str( egressDevice )
1527 else:
1528 main.log.error( "You must specify " +
1529 "the egress port" )
1530 # TODO: perhaps more meaningful return
1531 return main.FALSE
1532 else:
1533 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001534 for egressDevice, portEgress in zip( egressDeviceList,
1535 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001536 cmd += " " + \
1537 str( egressDevice ) + "/" +\
1538 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001539 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001540 main.log.error( "Device list and port list does not " +
1541 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001542 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001543 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001544 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001545 # If error, return error message
1546 if re.search( "Error", handle ):
1547 main.log.error( "Error in adding singlepoint-to-multipoint " +
1548 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001549 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001550 else:
1551 match = re.search('id=0x([\da-f]+),', handle)
1552 if match:
1553 return match.group()[3:-1]
1554 else:
1555 main.log.error( "Error, intent ID not found" )
1556 return None
Jon Hallc6793552016-01-19 14:18:37 -08001557 except AssertionError:
1558 main.log.exception( "" )
1559 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001560 except TypeError:
1561 main.log.exception( self.name + ": Object not as expected" )
1562 return None
shahshreyad0c80432014-12-04 16:56:05 -08001563 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001564 main.log.error( self.name + ": EOF exception found" )
1565 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001566 main.cleanup()
1567 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001569 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001570 main.cleanup()
1571 main.exit()
1572
Hari Krishna9e232602015-04-13 17:29:08 -07001573 def addMplsIntent(
1574 self,
1575 ingressDevice,
1576 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001577 ingressPort="",
1578 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001579 ethType="",
1580 ethSrc="",
1581 ethDst="",
1582 bandwidth="",
1583 lambdaAlloc=False,
1584 ipProto="",
1585 ipSrc="",
1586 ipDst="",
1587 tcpSrc="",
1588 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001589 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001590 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001591 priority=""):
1592 """
1593 Required:
1594 * ingressDevice: device id of ingress device
1595 * egressDevice: device id of egress device
1596 Optional:
1597 * ethType: specify ethType
1598 * ethSrc: specify ethSrc ( i.e. src mac addr )
1599 * ethDst: specify ethDst ( i.e. dst mac addr )
1600 * bandwidth: specify bandwidth capacity of link
1601 * lambdaAlloc: if True, intent will allocate lambda
1602 for the specified intent
1603 * ipProto: specify ip protocol
1604 * ipSrc: specify ip source address
1605 * ipDst: specify ip destination address
1606 * tcpSrc: specify tcp source port
1607 * tcpDst: specify tcp destination port
1608 * ingressLabel: Ingress MPLS label
1609 * egressLabel: Egress MPLS label
1610 Description:
1611 Adds MPLS intent by
1612 specifying device id's and optional fields
1613 Returns:
1614 A string of the intent id or None on error
1615
1616 NOTE: This function may change depending on the
1617 options developers provide for MPLS
1618 intent via cli
1619 """
1620 try:
1621 # If there are no optional arguments
1622 if not ethType and not ethSrc and not ethDst\
1623 and not bandwidth and not lambdaAlloc \
1624 and not ipProto and not ipSrc and not ipDst \
1625 and not tcpSrc and not tcpDst and not ingressLabel \
1626 and not egressLabel:
1627 cmd = "add-mpls-intent"
1628
1629 else:
1630 cmd = "add-mpls-intent"
1631
1632 if ethType:
1633 cmd += " --ethType " + str( ethType )
1634 if ethSrc:
1635 cmd += " --ethSrc " + str( ethSrc )
1636 if ethDst:
1637 cmd += " --ethDst " + str( ethDst )
1638 if bandwidth:
1639 cmd += " --bandwidth " + str( bandwidth )
1640 if lambdaAlloc:
1641 cmd += " --lambda "
1642 if ipProto:
1643 cmd += " --ipProto " + str( ipProto )
1644 if ipSrc:
1645 cmd += " --ipSrc " + str( ipSrc )
1646 if ipDst:
1647 cmd += " --ipDst " + str( ipDst )
1648 if tcpSrc:
1649 cmd += " --tcpSrc " + str( tcpSrc )
1650 if tcpDst:
1651 cmd += " --tcpDst " + str( tcpDst )
1652 if ingressLabel:
1653 cmd += " --ingressLabel " + str( ingressLabel )
1654 if egressLabel:
1655 cmd += " --egressLabel " + str( egressLabel )
1656 if priority:
1657 cmd += " --priority " + str( priority )
1658
1659 # Check whether the user appended the port
1660 # or provided it as an input
1661 if "/" in ingressDevice:
1662 cmd += " " + str( ingressDevice )
1663 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001664 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001665 main.log.error( "You must specify the ingress port" )
1666 return None
1667
1668 cmd += " " + \
1669 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001670 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001671
1672 if "/" in egressDevice:
1673 cmd += " " + str( egressDevice )
1674 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001675 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001676 main.log.error( "You must specify the egress port" )
1677 return None
1678
1679 cmd += " " +\
1680 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001681 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001682
1683 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001684 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001685 # If error, return error message
1686 if re.search( "Error", handle ):
1687 main.log.error( "Error in adding mpls intent" )
1688 return None
1689 else:
1690 # TODO: print out all the options in this message?
1691 main.log.info( "MPLS intent installed between " +
1692 str( ingressDevice ) + " and " +
1693 str( egressDevice ) )
1694 match = re.search('id=0x([\da-f]+),', handle)
1695 if match:
1696 return match.group()[3:-1]
1697 else:
1698 main.log.error( "Error, intent ID not found" )
1699 return None
Jon Hallc6793552016-01-19 14:18:37 -08001700 except AssertionError:
1701 main.log.exception( "" )
1702 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001703 except TypeError:
1704 main.log.exception( self.name + ": Object not as expected" )
1705 return None
1706 except pexpect.EOF:
1707 main.log.error( self.name + ": EOF exception found" )
1708 main.log.error( self.name + ": " + self.handle.before )
1709 main.cleanup()
1710 main.exit()
1711 except Exception:
1712 main.log.exception( self.name + ": Uncaught exception!" )
1713 main.cleanup()
1714 main.exit()
1715
Jon Hallefbd9792015-03-05 16:11:36 -08001716 def removeIntent( self, intentId, app='org.onosproject.cli',
1717 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001718 """
shahshreya1c818fc2015-02-26 13:44:08 -08001719 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001720 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001721 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001722 -p or --purge: Purge the intent from the store after removal
1723
Jon Halle3f39ff2015-01-13 11:50:53 -08001724 Returns:
1725 main.False on error and
1726 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001727 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001728 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001729 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001730 if purge:
1731 cmdStr += " -p"
1732 if sync:
1733 cmdStr += " -s"
1734
1735 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001737 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001738 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001739 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001740 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001741 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001742 # TODO: Should this be main.TRUE
1743 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001744 except AssertionError:
1745 main.log.exception( "" )
1746 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001747 except TypeError:
1748 main.log.exception( self.name + ": Object not as expected" )
1749 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001751 main.log.error( self.name + ": EOF exception found" )
1752 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001753 main.cleanup()
1754 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001755 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001757 main.cleanup()
1758 main.exit()
1759
Jeremy42df2e72016-02-23 16:37:46 -08001760 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1761 """
1762 Description:
1763 Remove all the intents
1764 Optional args:-
1765 -s or --sync: Waits for the removal before returning
1766 -p or --purge: Purge the intent from the store after removal
1767 Returns:
1768 Returns main.TRUE if all intents are removed, otherwise returns
1769 main.FALSE; Returns None for exception
1770 """
1771 try:
1772 cmdStr = "remove-intent"
1773 if purge:
1774 cmdStr += " -p"
1775 if sync:
1776 cmdStr += " -s"
1777
1778 cmdStr += " " + app
1779 handle = self.sendline( cmdStr )
1780 assert "Command not found:" not in handle, handle
1781 if re.search( "Error", handle ):
1782 main.log.error( "Error in removing intent" )
1783 return main.FALSE
1784 else:
1785 return main.TRUE
1786 except AssertionError:
1787 main.log.exception( "" )
1788 return None
1789 except TypeError:
1790 main.log.exception( self.name + ": Object not as expected" )
1791 return None
1792 except pexpect.EOF:
1793 main.log.error( self.name + ": EOF exception found" )
1794 main.log.error( self.name + ": " + self.handle.before )
1795 main.cleanup()
1796 main.exit()
1797 except Exception:
1798 main.log.exception( self.name + ": Uncaught exception!" )
1799 main.cleanup()
1800 main.exit()
1801
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001802 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001803 """
1804 Purges all WITHDRAWN Intents
1805 """
1806 try:
1807 cmdStr = "purge-intents"
1808 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001809 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001810 if re.search( "Error", handle ):
1811 main.log.error( "Error in purging intents" )
1812 return main.FALSE
1813 else:
1814 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001815 except AssertionError:
1816 main.log.exception( "" )
1817 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001818 except TypeError:
1819 main.log.exception( self.name + ": Object not as expected" )
1820 return None
1821 except pexpect.EOF:
1822 main.log.error( self.name + ": EOF exception found" )
1823 main.log.error( self.name + ": " + self.handle.before )
1824 main.cleanup()
1825 main.exit()
1826 except Exception:
1827 main.log.exception( self.name + ": Uncaught exception!" )
1828 main.cleanup()
1829 main.exit()
1830
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001832 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001833 NOTE: This method should be used after installing application:
1834 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001835 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001836 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001837 Description:
1838 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001839 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001840 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001841 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001843 cmdStr += " -j"
1844 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001845 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001846 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001847 except AssertionError:
1848 main.log.exception( "" )
1849 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001850 except TypeError:
1851 main.log.exception( self.name + ": Object not as expected" )
1852 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001853 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001854 main.log.error( self.name + ": EOF exception found" )
1855 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001856 main.cleanup()
1857 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001858 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001859 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001860 main.cleanup()
1861 main.exit()
1862
pingping-lin54b03372015-08-13 14:43:10 -07001863 def ipv4RouteNumber( self ):
1864 """
1865 NOTE: This method should be used after installing application:
1866 onos-app-sdnip
1867 Description:
1868 Obtain the total IPv4 routes number in the system
1869 """
1870 try:
1871 cmdStr = "routes -s -j"
1872 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001873 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001874 jsonResult = json.loads( handle )
1875 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001876 except AssertionError:
1877 main.log.exception( "" )
1878 return None
1879 except ( TypeError, ValueError ):
1880 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001881 return None
1882 except pexpect.EOF:
1883 main.log.error( self.name + ": EOF exception found" )
1884 main.log.error( self.name + ": " + self.handle.before )
1885 main.cleanup()
1886 main.exit()
1887 except Exception:
1888 main.log.exception( self.name + ": Uncaught exception!" )
1889 main.cleanup()
1890 main.exit()
1891
pingping-lin8244a3b2015-09-16 13:36:56 -07001892 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001893 """
andrewonlabe6745342014-10-17 14:29:13 -04001894 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001895 Obtain intents from the ONOS cli.
1896 Optional:
1897 * jsonFormat: Enable output formatting in json, default to True
1898 * summary: Whether only output the intent summary, defaults to False
1899 * type: Only output a certain type of intent. This options is valid
1900 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001901 """
andrewonlabe6745342014-10-17 14:29:13 -04001902 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001903 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001904 if summary:
1905 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001906 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001907 cmdStr += " -j"
1908 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001909 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001910 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001911 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001912 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001913 else:
Jon Hallff566d52016-01-15 14:45:36 -08001914 intentType = ""
1915 # IF we want the summary of a specific intent type
1916 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001917 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001918 if intentType in jsonResult.keys():
1919 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001920 else:
Jon Hallff566d52016-01-15 14:45:36 -08001921 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001922 return handle
1923 else:
1924 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001925 except AssertionError:
1926 main.log.exception( "" )
1927 return None
1928 except ( TypeError, ValueError ):
1929 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001930 return None
1931 except pexpect.EOF:
1932 main.log.error( self.name + ": EOF exception found" )
1933 main.log.error( self.name + ": " + self.handle.before )
1934 main.cleanup()
1935 main.exit()
1936 except Exception:
1937 main.log.exception( self.name + ": Uncaught exception!" )
1938 main.cleanup()
1939 main.exit()
1940
kelvin-onlab54400a92015-02-26 18:05:51 -08001941 def getIntentState(self, intentsId, intentsJson=None):
1942 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001943 Check intent state.
1944 Accepts a single intent ID (string type) or a list of intent IDs.
1945 Returns the state(string type) of the id if a single intent ID is
1946 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001947 Returns a dictionary with intent IDs as the key and its
1948 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001949 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001950 intentId: intent ID (string type)
1951 intentsJson: parsed json object from the onos:intents api
1952 Returns:
1953 state = An intent's state- INSTALL,WITHDRAWN etc.
1954 stateDict = Dictionary of intent's state. intent ID as the keys and
1955 state as the values.
1956 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001957 try:
1958 state = "State is Undefined"
1959 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001960 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001961 else:
Jon Hallc6793552016-01-19 14:18:37 -08001962 rawJson = intentsJson
1963 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001964 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001965 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001966 if intentsId == intent[ 'id' ]:
1967 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001968 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001969 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1970 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001971 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001972 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001973 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001974 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001975 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001976 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001977 if intentsId[ i ] == intents[ 'id' ]:
1978 stateDict[ 'state' ] = intents[ 'state' ]
1979 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001980 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001981 break
Jon Hallefbd9792015-03-05 16:11:36 -08001982 if len( intentsId ) != len( dictList ):
1983 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001984 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001985 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001986 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001987 return None
Jon Hallc6793552016-01-19 14:18:37 -08001988 except ( TypeError, ValueError ):
1989 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001990 return None
1991 except pexpect.EOF:
1992 main.log.error( self.name + ": EOF exception found" )
1993 main.log.error( self.name + ": " + self.handle.before )
1994 main.cleanup()
1995 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001996 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001997 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001998 main.cleanup()
1999 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002000
kelvin-onlabf512e942015-06-08 19:42:59 -07002001 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002002 """
2003 Description:
2004 Check intents state
2005 Required:
2006 intentsId - List of intents ID to be checked
2007 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002008 expectedState - Check the expected state(s) of each intents
2009 state in the list.
2010 *NOTE: You can pass in a list of expected state,
2011 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002012 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002013 Returns main.TRUE only if all intent are the same as expected states
2014 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002015 """
2016 try:
2017 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002018 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002019 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002020 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002021 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002022 "getting intents state" )
2023 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002024
2025 if isinstance( expectedState, types.StringType ):
2026 for intents in intentsDict:
2027 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002028 main.log.debug( self.name + " : Intent ID - " +
2029 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002030 " actual state = " +
2031 intents.get( 'state' )
2032 + " does not equal expected state = "
2033 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002034 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002035
2036 elif isinstance( expectedState, types.ListType ):
2037 for intents in intentsDict:
2038 if not any( state == intents.get( 'state' ) for state in
2039 expectedState ):
2040 main.log.debug( self.name + " : Intent ID - " +
2041 intents.get( 'id' ) +
2042 " actual state = " +
2043 intents.get( 'state' ) +
2044 " does not equal expected states = "
2045 + str( expectedState ) )
2046 returnValue = main.FALSE
2047
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002048 if returnValue == main.TRUE:
2049 main.log.info( self.name + ": All " +
2050 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002051 " intents are in " + str( expectedState ) +
2052 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002053 return returnValue
2054 except TypeError:
2055 main.log.exception( self.name + ": Object not as expected" )
2056 return None
2057 except pexpect.EOF:
2058 main.log.error( self.name + ": EOF exception found" )
2059 main.log.error( self.name + ": " + self.handle.before )
2060 main.cleanup()
2061 main.exit()
2062 except Exception:
2063 main.log.exception( self.name + ": Uncaught exception!" )
2064 main.cleanup()
2065 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002066
GlennRCed771242016-01-13 17:02:47 -08002067 def checkIntentSummary( self, timeout=60 ):
2068 """
2069 Description:
2070 Check the number of installed intents.
2071 Optional:
2072 timeout - the timeout for pexcept
2073 Return:
2074 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2075 , otherwise, returns main.FALSE.
2076 """
2077
2078 try:
2079 cmd = "intents -s -j"
2080
2081 # Check response if something wrong
2082 response = self.sendline( cmd, timeout=timeout )
2083 if response == None:
2084 return main.False
2085 response = json.loads( response )
2086
2087 # get total and installed number, see if they are match
2088 allState = response.get( 'all' )
2089 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002090 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002091 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002092 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002093 return main.FALSE
2094
Jon Hallc6793552016-01-19 14:18:37 -08002095 except ( TypeError, ValueError ):
2096 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002097 return None
2098 except pexpect.EOF:
2099 main.log.error( self.name + ": EOF exception found" )
2100 main.log.error( self.name + ": " + self.handle.before )
2101 main.cleanup()
2102 main.exit()
2103 except Exception:
2104 main.log.exception( self.name + ": Uncaught exception!" )
2105 main.cleanup()
2106 main.exit()
2107
2108 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002109 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002110 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002112 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002113 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002114 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002115 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002116 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002118 cmdStr += " -j "
2119 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002120 handle = self.sendline( cmdStr, timeout=timeout )
2121 assert "Command not found:" not in handle, handle
2122 if re.search( "Error:", handle ):
2123 main.log.error( self.name + ": flows() response: " +
2124 str( handle ) )
2125 return handle
2126 except AssertionError:
2127 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002128 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002129 except TypeError:
2130 main.log.exception( self.name + ": Object not as expected" )
2131 return None
Jon Hallc6793552016-01-19 14:18:37 -08002132 except pexpect.TIMEOUT:
2133 main.log.error( self.name + ": ONOS timeout" )
2134 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002136 main.log.error( self.name + ": EOF exception found" )
2137 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002138 main.cleanup()
2139 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002140 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002141 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002142 main.cleanup()
2143 main.exit()
2144
GlennRCed771242016-01-13 17:02:47 -08002145
Jon Hallc6793552016-01-19 14:18:37 -08002146 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002147 """
2148 Description:
GlennRCed771242016-01-13 17:02:47 -08002149 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002150 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2151 if the count of those states is 0, which means all current flows
2152 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002153 Optional:
GlennRCed771242016-01-13 17:02:47 -08002154 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002155 Return:
2156 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002157 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002158 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002159 """
2160 try:
GlennRCed771242016-01-13 17:02:47 -08002161 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2162 checkedStates = []
2163 statesCount = [0, 0, 0, 0]
2164 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002165 rawFlows = self.flows( state=s, timeout = timeout )
2166 checkedStates.append( json.loads( rawFlows ) )
2167 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002168 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002169 try:
2170 statesCount[i] += int( c.get( "flowCount" ) )
2171 except TypeError:
2172 main.log.exception( "Json object not as expected" )
2173 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002174
GlennRCed771242016-01-13 17:02:47 -08002175 # We want to count PENDING_ADD if isPENDING is true
2176 if isPENDING:
2177 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2178 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002179 else:
GlennRCed771242016-01-13 17:02:47 -08002180 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2181 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002182 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002183 except ( TypeError, ValueError ):
2184 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002185 return None
2186 except pexpect.EOF:
2187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
2189 main.cleanup()
2190 main.exit()
2191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
2193 main.cleanup()
2194 main.exit()
2195
GlennRCed771242016-01-13 17:02:47 -08002196 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2197 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002198 """
andrewonlab87852b02014-11-19 18:44:19 -05002199 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002200 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002201 a specific point-to-point intent definition
2202 Required:
GlennRCed771242016-01-13 17:02:47 -08002203 * ingress: specify source dpid
2204 * egress: specify destination dpid
2205 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002206 Optional:
GlennRCed771242016-01-13 17:02:47 -08002207 * offset: the keyOffset is where the next batch of intents
2208 will be installed
2209 Returns: If failed to push test intents, it will returen None,
2210 if successful, return true.
2211 Timeout expection will return None,
2212 TypeError will return false
2213 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002214 """
andrewonlab87852b02014-11-19 18:44:19 -05002215 try:
GlennRCed771242016-01-13 17:02:47 -08002216 if background:
2217 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002218 else:
GlennRCed771242016-01-13 17:02:47 -08002219 back = ""
2220 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002221 ingress,
2222 egress,
2223 batchSize,
2224 offset,
2225 back )
GlennRCed771242016-01-13 17:02:47 -08002226 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002227 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002228 main.log.info( response )
2229 if response == None:
2230 return None
2231
2232 # TODO: We should handle if there is failure in installation
2233 return main.TRUE
2234
Jon Hallc6793552016-01-19 14:18:37 -08002235 except AssertionError:
2236 main.log.exception( "" )
2237 return None
GlennRCed771242016-01-13 17:02:47 -08002238 except pexpect.TIMEOUT:
2239 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002240 return None
andrewonlab87852b02014-11-19 18:44:19 -05002241 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002242 main.log.error( self.name + ": EOF exception found" )
2243 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002244 main.cleanup()
2245 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002246 except TypeError:
2247 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002248 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002249 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002250 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002251 main.cleanup()
2252 main.exit()
2253
YPZhangf6f14a02016-01-28 15:17:31 -08002254 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002255 """
2256 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002257 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002258 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002259 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002260 """
YPZhange3109a72016-02-02 11:25:37 -08002261
YPZhangb5d3f832016-01-23 22:54:26 -08002262 try:
YPZhange3109a72016-02-02 11:25:37 -08002263 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002264 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002265 totalFlows = self.sendline( cmd, timeout=timeout )
2266
2267 if totalFlows == None:
2268 # if timeout, we will get total number of all flows, and subtract other states
2269 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2270 checkedStates = []
2271 totalFlows = 0
2272 statesCount = [0, 0, 0, 0]
2273
2274 # get total flows from summary
2275 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2276 totalFlows = int( response.get("flows") )
2277
2278 for s in states:
2279 rawFlows = self.flows( state=s, timeout = timeout )
2280 if rawFlows == None:
2281 # if timeout, return the total flows number from summary command
2282 return totalFlows
2283 checkedStates.append( json.loads( rawFlows ) )
2284
2285 # Calculate ADDED flows number, equal total subtracts others
2286 for i in range( len( states ) ):
2287 for c in checkedStates[i]:
2288 try:
2289 statesCount[i] += int( c.get( "flowCount" ) )
2290 except TypeError:
2291 main.log.exception( "Json object not as expected" )
2292 totalFlows = totalFlows - int( statesCount[i] )
2293 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2294
2295 return totalFlows
2296
2297 return totalFlows
2298
YPZhangb5d3f832016-01-23 22:54:26 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return None
2302 except pexpect.EOF:
2303 main.log.error( self.name + ": EOF exception found" )
2304 main.log.error( self.name + ": " + self.handle.before )
2305 main.cleanup()
2306 main.exit()
2307 except Exception:
2308 main.log.exception( self.name + ": Uncaught exception!" )
2309 main.cleanup()
2310 main.exit()
2311
2312 def getTotalIntentsNum( self ):
2313 """
2314 Description:
2315 Get the total number of intents, include every states.
2316 Return:
2317 The number of intents
2318 """
2319 try:
2320 cmd = "summary -j"
2321 response = self.sendline( cmd )
2322 if response == None:
2323 return -1
2324 response = json.loads( response )
2325 return int( response.get("intents") )
2326 except TypeError:
2327 main.log.exception( self.name + ": Object not as expected" )
2328 return None
2329 except pexpect.EOF:
2330 main.log.error( self.name + ": EOF exception found" )
2331 main.log.error( self.name + ": " + self.handle.before )
2332 main.cleanup()
2333 main.exit()
2334 except Exception:
2335 main.log.exception( self.name + ": Uncaught exception!" )
2336 main.cleanup()
2337 main.exit()
2338
kelvin-onlabd3b64892015-01-20 13:26:24 -08002339 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002340 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002341 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002342 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002343 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002344 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002345 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002346 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002347 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002348 cmdStr += " -j"
2349 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002350 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002351 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002352 except AssertionError:
2353 main.log.exception( "" )
2354 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002355 except TypeError:
2356 main.log.exception( self.name + ": Object not as expected" )
2357 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002358 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002359 main.log.error( self.name + ": EOF exception found" )
2360 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002361 main.cleanup()
2362 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002363 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002364 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002365 main.cleanup()
2366 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002367
kelvin-onlabd3b64892015-01-20 13:26:24 -08002368 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002369 """
2370 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002371 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002372 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002373 """
andrewonlab867212a2014-10-22 20:13:38 -04002374 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002375 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002376 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002377 cmdStr += " -j"
2378 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002379 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002380 if handle:
2381 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002382 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002383 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002384 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002385 else:
2386 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002387 except AssertionError:
2388 main.log.exception( "" )
2389 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002390 except TypeError:
2391 main.log.exception( self.name + ": Object not as expected" )
2392 return None
andrewonlab867212a2014-10-22 20:13:38 -04002393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002394 main.log.error( self.name + ": EOF exception found" )
2395 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002396 main.cleanup()
2397 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002398 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002399 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002400 main.cleanup()
2401 main.exit()
2402
kelvin8ec71442015-01-15 16:57:00 -08002403 # Wrapper functions ****************
2404 # Wrapper functions use existing driver
2405 # functions and extends their use case.
2406 # For example, we may use the output of
2407 # a normal driver function, and parse it
2408 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002409
kelvin-onlabd3b64892015-01-20 13:26:24 -08002410 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002411 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002412 Description:
2413 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002414 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002415 try:
kelvin8ec71442015-01-15 16:57:00 -08002416 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002417 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002418 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002419
kelvin8ec71442015-01-15 16:57:00 -08002420 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002421 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2422 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002423 match = re.search('id=0x([\da-f]+),', intents)
2424 if match:
2425 tmpId = match.group()[3:-1]
2426 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002427 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002428
Jon Halld4d4b372015-01-28 16:02:41 -08002429 except TypeError:
2430 main.log.exception( self.name + ": Object not as expected" )
2431 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002432 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002433 main.log.error( self.name + ": EOF exception found" )
2434 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002435 main.cleanup()
2436 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002437 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002438 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002439 main.cleanup()
2440 main.exit()
2441
Jon Hall30b82fa2015-03-04 17:15:43 -08002442 def FlowAddedCount( self, deviceId ):
2443 """
2444 Determine the number of flow rules for the given device id that are
2445 in the added state
2446 """
2447 try:
2448 cmdStr = "flows any " + str( deviceId ) + " | " +\
2449 "grep 'state=ADDED' | wc -l"
2450 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002451 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002452 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002453 except AssertionError:
2454 main.log.exception( "" )
2455 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002456 except pexpect.EOF:
2457 main.log.error( self.name + ": EOF exception found" )
2458 main.log.error( self.name + ": " + self.handle.before )
2459 main.cleanup()
2460 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002461 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002462 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002463 main.cleanup()
2464 main.exit()
2465
kelvin-onlabd3b64892015-01-20 13:26:24 -08002466 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002467 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002468 Use 'devices' function to obtain list of all devices
2469 and parse the result to obtain a list of all device
2470 id's. Returns this list. Returns empty list if no
2471 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002472 List is ordered sequentially
2473
andrewonlab3e15ead2014-10-15 14:21:34 -04002474 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002475 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002476 the ids. By obtaining the list of device ids on the fly,
2477 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002478 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002479 try:
kelvin8ec71442015-01-15 16:57:00 -08002480 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002481 devicesStr = self.devices( jsonFormat=False )
2482 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002483
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002485 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002486 return idList
kelvin8ec71442015-01-15 16:57:00 -08002487
2488 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002489 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002490 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002491 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002492 # Split list further into arguments before and after string
2493 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002494 # append to idList
2495 for arg in tempList:
2496 idList.append( arg.split( "id=" )[ 1 ] )
2497 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002498
Jon Halld4d4b372015-01-28 16:02:41 -08002499 except TypeError:
2500 main.log.exception( self.name + ": Object not as expected" )
2501 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002502 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002505 main.cleanup()
2506 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002507 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002508 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002509 main.cleanup()
2510 main.exit()
2511
kelvin-onlabd3b64892015-01-20 13:26:24 -08002512 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002513 """
andrewonlab7c211572014-10-15 16:45:20 -04002514 Uses 'nodes' function to obtain list of all nodes
2515 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002516 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002517 Returns:
2518 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002519 """
andrewonlab7c211572014-10-15 16:45:20 -04002520 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002521 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002522 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002523 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002524 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002525 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002526 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002527 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002528 nodesJson = json.loads( nodesStr )
2529 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002531 except ( TypeError, ValueError ):
2532 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002533 return None
andrewonlab7c211572014-10-15 16:45:20 -04002534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002535 main.log.error( self.name + ": EOF exception found" )
2536 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002537 main.cleanup()
2538 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002540 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002541 main.cleanup()
2542 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002543
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002545 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002546 Return the first device from the devices api whose 'id' contains 'dpid'
2547 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002548 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002549 try:
kelvin8ec71442015-01-15 16:57:00 -08002550 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002551 return None
2552 else:
kelvin8ec71442015-01-15 16:57:00 -08002553 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002554 rawDevices = self.devices()
2555 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002556 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002557 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002558 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2559 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002560 return device
2561 return None
Jon Hallc6793552016-01-19 14:18:37 -08002562 except ( TypeError, ValueError ):
2563 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002564 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002565 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002566 main.log.error( self.name + ": EOF exception found" )
2567 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002568 main.cleanup()
2569 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002570 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002571 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002572 main.cleanup()
2573 main.exit()
2574
kelvin-onlabd3b64892015-01-20 13:26:24 -08002575 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002576 """
Jon Hallefbd9792015-03-05 16:11:36 -08002577 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002578 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002579 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002580
Jon Hall42db6dc2014-10-24 19:03:48 -04002581 Params: ip = ip used for the onos cli
2582 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002583 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002584 logLevel = level to log to. Currently accepts
2585 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002586
2587
kelvin-onlabd3b64892015-01-20 13:26:24 -08002588 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002589
Jon Hallefbd9792015-03-05 16:11:36 -08002590 Returns: main.TRUE if the number of switches and links are correct,
2591 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002592 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002593 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002594 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002595 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002596 if topology == {}:
2597 return main.ERROR
2598 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002599 # Is the number of switches is what we expected
2600 devices = topology.get( 'devices', False )
2601 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002602 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002603 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002604 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002605 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002606 linkCheck = ( int( links ) == int( numolink ) )
2607 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002608 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002609 output += "The number of links and switches match " +\
2610 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002611 result = main.TRUE
2612 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002613 output += "The number of links and switches does not match " +\
2614 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002615 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002616 output = output + "\n ONOS sees %i devices (%i expected) \
2617 and %i links (%i expected)" % (
2618 int( devices ), int( numoswitch ), int( links ),
2619 int( numolink ) )
2620 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002621 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002622 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002623 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002624 else:
Jon Hall390696c2015-05-05 17:13:41 -07002625 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002626 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002627 except TypeError:
2628 main.log.exception( self.name + ": Object not as expected" )
2629 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002631 main.log.error( self.name + ": EOF exception found" )
2632 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002633 main.cleanup()
2634 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002635 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002636 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002637 main.cleanup()
2638 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002639
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002641 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002642 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002643 deviceId must be the id of a device as seen in the onos devices command
2644 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002645 role must be either master, standby, or none
2646
Jon Halle3f39ff2015-01-13 11:50:53 -08002647 Returns:
2648 main.TRUE or main.FALSE based on argument verification and
2649 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002650 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002651 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002652 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002653 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002654 cmdStr = "device-role " +\
2655 str( deviceId ) + " " +\
2656 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002657 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002658 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002659 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002660 if re.search( "Error", handle ):
2661 # end color output to escape any colours
2662 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002663 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002664 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002665 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002666 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002667 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002668 main.log.error( "Invalid 'role' given to device_role(). " +
2669 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002670 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002671 except AssertionError:
2672 main.log.exception( "" )
2673 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002674 except TypeError:
2675 main.log.exception( self.name + ": Object not as expected" )
2676 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002677 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002678 main.log.error( self.name + ": EOF exception found" )
2679 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002680 main.cleanup()
2681 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002682 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002683 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002684 main.cleanup()
2685 main.exit()
2686
kelvin-onlabd3b64892015-01-20 13:26:24 -08002687 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002688 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002689 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002690 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002691 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002692 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002693 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002694 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002695 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002696 cmdStr += " -j"
2697 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002698 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002699 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002700 except AssertionError:
2701 main.log.exception( "" )
2702 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002703 except TypeError:
2704 main.log.exception( self.name + ": Object not as expected" )
2705 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002706 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002707 main.log.error( self.name + ": EOF exception found" )
2708 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002709 main.cleanup()
2710 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002711 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002712 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002713 main.cleanup()
2714 main.exit()
2715
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002717 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002718 CLI command to get the current leader for the Election test application
2719 NOTE: Requires installation of the onos-app-election feature
2720 Returns: Node IP of the leader if one exists
2721 None if none exists
2722 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002723 """
Jon Hall94fd0472014-12-08 11:52:42 -08002724 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 cmdStr = "election-test-leader"
2726 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002727 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002728 # Leader
2729 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002730 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 nodeSearch = re.search( leaderPattern, response )
2732 if nodeSearch:
2733 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002734 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002735 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002736 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002737 # no leader
2738 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002739 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002740 nullSearch = re.search( nullPattern, response )
2741 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002742 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002743 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002744 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002745 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002746 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002747 if re.search( errorPattern, response ):
2748 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002749 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002750 return main.FALSE
2751 else:
Jon Hall390696c2015-05-05 17:13:41 -07002752 main.log.error( "Error in electionTestLeader on " + self.name +
2753 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002754 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002755 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002756 except AssertionError:
2757 main.log.exception( "" )
2758 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002759 except TypeError:
2760 main.log.exception( self.name + ": Object not as expected" )
2761 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002762 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002763 main.log.error( self.name + ": EOF exception found" )
2764 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002765 main.cleanup()
2766 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002767 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002768 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002769 main.cleanup()
2770 main.exit()
2771
kelvin-onlabd3b64892015-01-20 13:26:24 -08002772 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002773 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002774 CLI command to run for leadership of the Election test application.
2775 NOTE: Requires installation of the onos-app-election feature
2776 Returns: Main.TRUE on success
2777 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002778 """
Jon Hall94fd0472014-12-08 11:52:42 -08002779 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002780 cmdStr = "election-test-run"
2781 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002782 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002783 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002784 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002785 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002786 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002787 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002788 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002789 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002790 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002791 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002792 errorPattern = "Command\snot\sfound"
2793 if re.search( errorPattern, response ):
2794 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002795 return main.FALSE
2796 else:
Jon Hall390696c2015-05-05 17:13:41 -07002797 main.log.error( "Error in electionTestRun on " + self.name +
2798 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002799 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002800 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002801 except AssertionError:
2802 main.log.exception( "" )
2803 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002804 except TypeError:
2805 main.log.exception( self.name + ": Object not as expected" )
2806 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002807 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002808 main.log.error( self.name + ": EOF exception found" )
2809 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002810 main.cleanup()
2811 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002813 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002814 main.cleanup()
2815 main.exit()
2816
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002818 """
Jon Hall94fd0472014-12-08 11:52:42 -08002819 * CLI command to withdraw the local node from leadership election for
2820 * the Election test application.
2821 #NOTE: Requires installation of the onos-app-election feature
2822 Returns: Main.TRUE on success
2823 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002824 """
Jon Hall94fd0472014-12-08 11:52:42 -08002825 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 cmdStr = "election-test-withdraw"
2827 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002828 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002829 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002830 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002831 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002832 if re.search( successPattern, response ):
2833 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002834 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002835 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002836 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002837 errorPattern = "Command\snot\sfound"
2838 if re.search( errorPattern, response ):
2839 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002840 return main.FALSE
2841 else:
Jon Hall390696c2015-05-05 17:13:41 -07002842 main.log.error( "Error in electionTestWithdraw on " +
2843 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002844 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002845 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002846 except AssertionError:
2847 main.log.exception( "" )
2848 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002849 except TypeError:
2850 main.log.exception( self.name + ": Object not as expected" )
2851 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002852 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002853 main.log.error( self.name + ": EOF exception found" )
2854 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002855 main.cleanup()
2856 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002857 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002858 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002859 main.cleanup()
2860 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002861
kelvin8ec71442015-01-15 16:57:00 -08002862 def getDevicePortsEnabledCount( self, dpid ):
2863 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002864 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002865 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002866 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002867 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002868 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2869 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002870 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002871 if re.search( "No such device", output ):
2872 main.log.error( "Error in getting ports" )
2873 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002874 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002875 return output
Jon Hallc6793552016-01-19 14:18:37 -08002876 except AssertionError:
2877 main.log.exception( "" )
2878 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002879 except TypeError:
2880 main.log.exception( self.name + ": Object not as expected" )
2881 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002883 main.log.error( self.name + ": EOF exception found" )
2884 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002885 main.cleanup()
2886 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002887 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002888 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002889 main.cleanup()
2890 main.exit()
2891
kelvin8ec71442015-01-15 16:57:00 -08002892 def getDeviceLinksActiveCount( self, dpid ):
2893 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002894 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002895 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002896 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002897 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002898 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2899 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002900 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002901 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002902 main.log.error( "Error in getting ports " )
2903 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002904 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002905 return output
Jon Hallc6793552016-01-19 14:18:37 -08002906 except AssertionError:
2907 main.log.exception( "" )
2908 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002909 except TypeError:
2910 main.log.exception( self.name + ": Object not as expected" )
2911 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002913 main.log.error( self.name + ": EOF exception found" )
2914 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002915 main.cleanup()
2916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002918 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002919 main.cleanup()
2920 main.exit()
2921
kelvin8ec71442015-01-15 16:57:00 -08002922 def getAllIntentIds( self ):
2923 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002924 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002925 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002926 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 cmdStr = "onos:intents | grep id="
2928 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002929 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002930 if re.search( "Error", output ):
2931 main.log.error( "Error in getting ports" )
2932 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002933 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002934 return output
Jon Hallc6793552016-01-19 14:18:37 -08002935 except AssertionError:
2936 main.log.exception( "" )
2937 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002938 except TypeError:
2939 main.log.exception( self.name + ": Object not as expected" )
2940 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002942 main.log.error( self.name + ": EOF exception found" )
2943 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002944 main.cleanup()
2945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002947 main.log.exception( self.name + ": Uncaught exception!" )
2948 main.cleanup()
2949 main.exit()
2950
Jon Hall73509952015-02-24 16:42:56 -08002951 def intentSummary( self ):
2952 """
Jon Hallefbd9792015-03-05 16:11:36 -08002953 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002954 """
2955 try:
2956 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002957 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002958 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002959 states.append( intent.get( 'state', None ) )
2960 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002961 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002962 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002963 except ( TypeError, ValueError ):
2964 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002965 return None
2966 except pexpect.EOF:
2967 main.log.error( self.name + ": EOF exception found" )
2968 main.log.error( self.name + ": " + self.handle.before )
2969 main.cleanup()
2970 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002971 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002972 main.log.exception( self.name + ": Uncaught exception!" )
2973 main.cleanup()
2974 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002975
Jon Hall61282e32015-03-19 11:34:11 -07002976 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002977 """
2978 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002979 Optional argument:
2980 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002981 """
Jon Hall63604932015-02-26 17:09:50 -08002982 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002983 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002984 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002985 cmdStr += " -j"
2986 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002987 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002988 return output
Jon Hallc6793552016-01-19 14:18:37 -08002989 except AssertionError:
2990 main.log.exception( "" )
2991 return None
Jon Hall63604932015-02-26 17:09:50 -08002992 except TypeError:
2993 main.log.exception( self.name + ": Object not as expected" )
2994 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002995 except pexpect.EOF:
2996 main.log.error( self.name + ": EOF exception found" )
2997 main.log.error( self.name + ": " + self.handle.before )
2998 main.cleanup()
2999 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003000 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003001 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003002 main.cleanup()
3003 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003004
acsmarsa4a4d1e2015-07-10 16:01:24 -07003005 def leaderCandidates( self, jsonFormat=True ):
3006 """
3007 Returns the output of the leaders -c command.
3008 Optional argument:
3009 * jsonFormat - boolean indicating if you want output in json
3010 """
3011 try:
3012 cmdStr = "onos:leaders -c"
3013 if jsonFormat:
3014 cmdStr += " -j"
3015 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003016 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003017 return output
Jon Hallc6793552016-01-19 14:18:37 -08003018 except AssertionError:
3019 main.log.exception( "" )
3020 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003021 except TypeError:
3022 main.log.exception( self.name + ": Object not as expected" )
3023 return None
3024 except pexpect.EOF:
3025 main.log.error( self.name + ": EOF exception found" )
3026 main.log.error( self.name + ": " + self.handle.before )
3027 main.cleanup()
3028 main.exit()
3029 except Exception:
3030 main.log.exception( self.name + ": Uncaught exception!" )
3031 main.cleanup()
3032 main.exit()
3033
Jon Hallc6793552016-01-19 14:18:37 -08003034 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003035 """
3036 Returns a list in format [leader,candidate1,candidate2,...] for a given
3037 topic parameter and an empty list if the topic doesn't exist
3038 If no leader is elected leader in the returned list will be "none"
3039 Returns None if there is a type error processing the json object
3040 """
3041 try:
Jon Hall6e709752016-02-01 13:38:46 -08003042 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003043 rawOutput = self.sendline( cmdStr )
3044 assert "Command not found:" not in rawOutput, rawOutput
3045 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003046 results = []
3047 for dict in output:
3048 if dict["topic"] == topic:
3049 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003050 candidates = re.split( ", ", dict["candidates"][1:-1] )
3051 results.append( leader )
3052 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003053 return results
Jon Hallc6793552016-01-19 14:18:37 -08003054 except AssertionError:
3055 main.log.exception( "" )
3056 return None
3057 except ( TypeError, ValueError ):
3058 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003059 return None
3060 except pexpect.EOF:
3061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
3063 main.cleanup()
3064 main.exit()
3065 except Exception:
3066 main.log.exception( self.name + ": Uncaught exception!" )
3067 main.cleanup()
3068 main.exit()
3069
Jon Hall61282e32015-03-19 11:34:11 -07003070 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003071 """
3072 Returns the output of the intent Pending map.
3073 """
Jon Hall63604932015-02-26 17:09:50 -08003074 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003075 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003076 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003077 cmdStr += " -j"
3078 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003079 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003080 return output
Jon Hallc6793552016-01-19 14:18:37 -08003081 except AssertionError:
3082 main.log.exception( "" )
3083 return None
Jon Hall63604932015-02-26 17:09:50 -08003084 except TypeError:
3085 main.log.exception( self.name + ": Object not as expected" )
3086 return None
3087 except pexpect.EOF:
3088 main.log.error( self.name + ": EOF exception found" )
3089 main.log.error( self.name + ": " + self.handle.before )
3090 main.cleanup()
3091 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003092 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003093 main.log.exception( self.name + ": Uncaught exception!" )
3094 main.cleanup()
3095 main.exit()
3096
Jon Hall61282e32015-03-19 11:34:11 -07003097 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003098 """
3099 Returns the output of the raft partitions command for ONOS.
3100 """
Jon Hall61282e32015-03-19 11:34:11 -07003101 # Sample JSON
3102 # {
3103 # "leader": "tcp://10.128.30.11:7238",
3104 # "members": [
3105 # "tcp://10.128.30.11:7238",
3106 # "tcp://10.128.30.17:7238",
3107 # "tcp://10.128.30.13:7238",
3108 # ],
3109 # "name": "p1",
3110 # "term": 3
3111 # },
Jon Hall63604932015-02-26 17:09:50 -08003112 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003113 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003114 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003115 cmdStr += " -j"
3116 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003117 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003118 return output
Jon Hallc6793552016-01-19 14:18:37 -08003119 except AssertionError:
3120 main.log.exception( "" )
3121 return None
Jon Hall63604932015-02-26 17:09:50 -08003122 except TypeError:
3123 main.log.exception( self.name + ": Object not as expected" )
3124 return None
3125 except pexpect.EOF:
3126 main.log.error( self.name + ": EOF exception found" )
3127 main.log.error( self.name + ": " + self.handle.before )
3128 main.cleanup()
3129 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003130 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003131 main.log.exception( self.name + ": Uncaught exception!" )
3132 main.cleanup()
3133 main.exit()
3134
Jon Hallbe379602015-03-24 13:39:32 -07003135 def apps( self, jsonFormat=True ):
3136 """
3137 Returns the output of the apps command for ONOS. This command lists
3138 information about installed ONOS applications
3139 """
3140 # Sample JSON object
3141 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3142 # "description":"ONOS OpenFlow protocol southbound providers",
3143 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3144 # "features":"[onos-openflow]","state":"ACTIVE"}]
3145 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003146 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003147 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003148 cmdStr += " -j"
3149 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003150 assert "Command not found:" not in output, output
3151 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003152 return output
Jon Hallbe379602015-03-24 13:39:32 -07003153 # FIXME: look at specific exceptions/Errors
3154 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003155 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003156 return None
3157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return None
3160 except pexpect.EOF:
3161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
3163 main.cleanup()
3164 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003165 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003166 main.log.exception( self.name + ": Uncaught exception!" )
3167 main.cleanup()
3168 main.exit()
3169
Jon Hall146f1522015-03-24 15:33:24 -07003170 def appStatus( self, appName ):
3171 """
3172 Uses the onos:apps cli command to return the status of an application.
3173 Returns:
3174 "ACTIVE" - If app is installed and activated
3175 "INSTALLED" - If app is installed and deactivated
3176 "UNINSTALLED" - If app is not installed
3177 None - on error
3178 """
Jon Hall146f1522015-03-24 15:33:24 -07003179 try:
3180 if not isinstance( appName, types.StringType ):
3181 main.log.error( self.name + ".appStatus(): appName must be" +
3182 " a string" )
3183 return None
3184 output = self.apps( jsonFormat=True )
3185 appsJson = json.loads( output )
3186 state = None
3187 for app in appsJson:
3188 if appName == app.get('name'):
3189 state = app.get('state')
3190 break
3191 if state == "ACTIVE" or state == "INSTALLED":
3192 return state
3193 elif state is None:
3194 return "UNINSTALLED"
3195 elif state:
3196 main.log.error( "Unexpected state from 'onos:apps': " +
3197 str( state ) )
3198 return state
Jon Hallc6793552016-01-19 14:18:37 -08003199 except ( TypeError, ValueError ):
3200 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3201 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003202 return None
3203 except pexpect.EOF:
3204 main.log.error( self.name + ": EOF exception found" )
3205 main.log.error( self.name + ": " + self.handle.before )
3206 main.cleanup()
3207 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003208 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003209 main.log.exception( self.name + ": Uncaught exception!" )
3210 main.cleanup()
3211 main.exit()
3212
Jon Hallbe379602015-03-24 13:39:32 -07003213 def app( self, appName, option ):
3214 """
3215 Interacts with the app command for ONOS. This command manages
3216 application inventory.
3217 """
Jon Hallbe379602015-03-24 13:39:32 -07003218 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003219 # Validate argument types
3220 valid = True
3221 if not isinstance( appName, types.StringType ):
3222 main.log.error( self.name + ".app(): appName must be a " +
3223 "string" )
3224 valid = False
3225 if not isinstance( option, types.StringType ):
3226 main.log.error( self.name + ".app(): option must be a string" )
3227 valid = False
3228 if not valid:
3229 return main.FALSE
3230 # Validate Option
3231 option = option.lower()
3232 # NOTE: Install may become a valid option
3233 if option == "activate":
3234 pass
3235 elif option == "deactivate":
3236 pass
3237 elif option == "uninstall":
3238 pass
3239 else:
3240 # Invalid option
3241 main.log.error( "The ONOS app command argument only takes " +
3242 "the values: (activate|deactivate|uninstall)" +
3243 "; was given '" + option + "'")
3244 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003245 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003246 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003247 if "Error executing command" in output:
3248 main.log.error( "Error in processing onos:app command: " +
3249 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003250 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003251 elif "No such application" in output:
3252 main.log.error( "The application '" + appName +
3253 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003254 return main.FALSE
3255 elif "Command not found:" in output:
3256 main.log.error( "Error in processing onos:app command: " +
3257 str( output ) )
3258 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003259 elif "Unsupported command:" in output:
3260 main.log.error( "Incorrect command given to 'app': " +
3261 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003262 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003263 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003264 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003265 return main.TRUE
3266 except TypeError:
3267 main.log.exception( self.name + ": Object not as expected" )
3268 return main.ERROR
3269 except pexpect.EOF:
3270 main.log.error( self.name + ": EOF exception found" )
3271 main.log.error( self.name + ": " + self.handle.before )
3272 main.cleanup()
3273 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003274 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003275 main.log.exception( self.name + ": Uncaught exception!" )
3276 main.cleanup()
3277 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003278
Jon Hallbd16b922015-03-26 17:53:15 -07003279 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003280 """
3281 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003282 appName is the hierarchical app name, not the feature name
3283 If check is True, method will check the status of the app after the
3284 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003285 Returns main.TRUE if the command was successfully sent
3286 main.FALSE if the cli responded with an error or given
3287 incorrect input
3288 """
3289 try:
3290 if not isinstance( appName, types.StringType ):
3291 main.log.error( self.name + ".activateApp(): appName must be" +
3292 " a string" )
3293 return main.FALSE
3294 status = self.appStatus( appName )
3295 if status == "INSTALLED":
3296 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003297 if check and response == main.TRUE:
3298 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003299 status = self.appStatus( appName )
3300 if status == "ACTIVE":
3301 return main.TRUE
3302 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003303 main.log.debug( "The state of application " +
3304 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003305 time.sleep( 1 )
3306 return main.FALSE
3307 else: # not 'check' or command didn't succeed
3308 return response
Jon Hall146f1522015-03-24 15:33:24 -07003309 elif status == "ACTIVE":
3310 return main.TRUE
3311 elif status == "UNINSTALLED":
3312 main.log.error( self.name + ": Tried to activate the " +
3313 "application '" + appName + "' which is not " +
3314 "installed." )
3315 else:
3316 main.log.error( "Unexpected return value from appStatus: " +
3317 str( status ) )
3318 return main.ERROR
3319 except TypeError:
3320 main.log.exception( self.name + ": Object not as expected" )
3321 return main.ERROR
3322 except pexpect.EOF:
3323 main.log.error( self.name + ": EOF exception found" )
3324 main.log.error( self.name + ": " + self.handle.before )
3325 main.cleanup()
3326 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003327 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003328 main.log.exception( self.name + ": Uncaught exception!" )
3329 main.cleanup()
3330 main.exit()
3331
Jon Hallbd16b922015-03-26 17:53:15 -07003332 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003333 """
3334 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003335 appName is the hierarchical app name, not the feature name
3336 If check is True, method will check the status of the app after the
3337 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003338 Returns main.TRUE if the command was successfully sent
3339 main.FALSE if the cli responded with an error or given
3340 incorrect input
3341 """
3342 try:
3343 if not isinstance( appName, types.StringType ):
3344 main.log.error( self.name + ".deactivateApp(): appName must " +
3345 "be a string" )
3346 return main.FALSE
3347 status = self.appStatus( appName )
3348 if status == "INSTALLED":
3349 return main.TRUE
3350 elif status == "ACTIVE":
3351 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003352 if check and response == main.TRUE:
3353 for i in range(10): # try 10 times then give up
3354 status = self.appStatus( appName )
3355 if status == "INSTALLED":
3356 return main.TRUE
3357 else:
3358 time.sleep( 1 )
3359 return main.FALSE
3360 else: # not check or command didn't succeed
3361 return response
Jon Hall146f1522015-03-24 15:33:24 -07003362 elif status == "UNINSTALLED":
3363 main.log.warn( self.name + ": Tried to deactivate the " +
3364 "application '" + appName + "' which is not " +
3365 "installed." )
3366 return main.TRUE
3367 else:
3368 main.log.error( "Unexpected return value from appStatus: " +
3369 str( status ) )
3370 return main.ERROR
3371 except TypeError:
3372 main.log.exception( self.name + ": Object not as expected" )
3373 return main.ERROR
3374 except pexpect.EOF:
3375 main.log.error( self.name + ": EOF exception found" )
3376 main.log.error( self.name + ": " + self.handle.before )
3377 main.cleanup()
3378 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003379 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003380 main.log.exception( self.name + ": Uncaught exception!" )
3381 main.cleanup()
3382 main.exit()
3383
Jon Hallbd16b922015-03-26 17:53:15 -07003384 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003385 """
3386 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003387 appName is the hierarchical app name, not the feature name
3388 If check is True, method will check the status of the app after the
3389 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003390 Returns main.TRUE if the command was successfully sent
3391 main.FALSE if the cli responded with an error or given
3392 incorrect input
3393 """
3394 # TODO: check with Thomas about the state machine for apps
3395 try:
3396 if not isinstance( appName, types.StringType ):
3397 main.log.error( self.name + ".uninstallApp(): appName must " +
3398 "be a string" )
3399 return main.FALSE
3400 status = self.appStatus( appName )
3401 if status == "INSTALLED":
3402 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003403 if check and response == main.TRUE:
3404 for i in range(10): # try 10 times then give up
3405 status = self.appStatus( appName )
3406 if status == "UNINSTALLED":
3407 return main.TRUE
3408 else:
3409 time.sleep( 1 )
3410 return main.FALSE
3411 else: # not check or command didn't succeed
3412 return response
Jon Hall146f1522015-03-24 15:33:24 -07003413 elif status == "ACTIVE":
3414 main.log.warn( self.name + ": Tried to uninstall the " +
3415 "application '" + appName + "' which is " +
3416 "currently active." )
3417 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003418 if check and response == main.TRUE:
3419 for i in range(10): # try 10 times then give up
3420 status = self.appStatus( appName )
3421 if status == "UNINSTALLED":
3422 return main.TRUE
3423 else:
3424 time.sleep( 1 )
3425 return main.FALSE
3426 else: # not check or command didn't succeed
3427 return response
Jon Hall146f1522015-03-24 15:33:24 -07003428 elif status == "UNINSTALLED":
3429 return main.TRUE
3430 else:
3431 main.log.error( "Unexpected return value from appStatus: " +
3432 str( status ) )
3433 return main.ERROR
3434 except TypeError:
3435 main.log.exception( self.name + ": Object not as expected" )
3436 return main.ERROR
3437 except pexpect.EOF:
3438 main.log.error( self.name + ": EOF exception found" )
3439 main.log.error( self.name + ": " + self.handle.before )
3440 main.cleanup()
3441 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003442 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003443 main.log.exception( self.name + ": Uncaught exception!" )
3444 main.cleanup()
3445 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003446
3447 def appIDs( self, jsonFormat=True ):
3448 """
3449 Show the mappings between app id and app names given by the 'app-ids'
3450 cli command
3451 """
3452 try:
3453 cmdStr = "app-ids"
3454 if jsonFormat:
3455 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003456 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003457 assert "Command not found:" not in output, output
3458 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003459 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003460 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003461 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003462 return None
3463 except TypeError:
3464 main.log.exception( self.name + ": Object not as expected" )
3465 return None
3466 except pexpect.EOF:
3467 main.log.error( self.name + ": EOF exception found" )
3468 main.log.error( self.name + ": " + self.handle.before )
3469 main.cleanup()
3470 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003471 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003472 main.log.exception( self.name + ": Uncaught exception!" )
3473 main.cleanup()
3474 main.exit()
3475
3476 def appToIDCheck( self ):
3477 """
3478 This method will check that each application's ID listed in 'apps' is
3479 the same as the ID listed in 'app-ids'. The check will also check that
3480 there are no duplicate IDs issued. Note that an app ID should be
3481 a globaly unique numerical identifier for app/app-like features. Once
3482 an ID is registered, the ID is never freed up so that if an app is
3483 reinstalled it will have the same ID.
3484
3485 Returns: main.TRUE if the check passes and
3486 main.FALSE if the check fails or
3487 main.ERROR if there is some error in processing the test
3488 """
3489 try:
Jon Hall390696c2015-05-05 17:13:41 -07003490 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003491 rawJson = self.appIDs( jsonFormat=True )
3492 if rawJson:
3493 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003494 else:
Jon Hallc6793552016-01-19 14:18:37 -08003495 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003496 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003497 rawJson = self.apps( jsonFormat=True )
3498 if rawJson:
3499 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003500 else:
Jon Hallc6793552016-01-19 14:18:37 -08003501 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003502 bail = True
3503 if bail:
3504 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003505 result = main.TRUE
3506 for app in apps:
3507 appID = app.get( 'id' )
3508 if appID is None:
3509 main.log.error( "Error parsing app: " + str( app ) )
3510 result = main.FALSE
3511 appName = app.get( 'name' )
3512 if appName is None:
3513 main.log.error( "Error parsing app: " + str( app ) )
3514 result = main.FALSE
3515 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003516 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003517 # main.log.debug( "Comparing " + str( app ) + " to " +
3518 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003519 if not current: # if ids doesn't have this id
3520 result = main.FALSE
3521 main.log.error( "'app-ids' does not have the ID for " +
3522 str( appName ) + " that apps does." )
3523 elif len( current ) > 1:
3524 # there is more than one app with this ID
3525 result = main.FALSE
3526 # We will log this later in the method
3527 elif not current[0][ 'name' ] == appName:
3528 currentName = current[0][ 'name' ]
3529 result = main.FALSE
3530 main.log.error( "'app-ids' has " + str( currentName ) +
3531 " registered under id:" + str( appID ) +
3532 " but 'apps' has " + str( appName ) )
3533 else:
3534 pass # id and name match!
3535 # now make sure that app-ids has no duplicates
3536 idsList = []
3537 namesList = []
3538 for item in ids:
3539 idsList.append( item[ 'id' ] )
3540 namesList.append( item[ 'name' ] )
3541 if len( idsList ) != len( set( idsList ) ) or\
3542 len( namesList ) != len( set( namesList ) ):
3543 main.log.error( "'app-ids' has some duplicate entries: \n"
3544 + json.dumps( ids,
3545 sort_keys=True,
3546 indent=4,
3547 separators=( ',', ': ' ) ) )
3548 result = main.FALSE
3549 return result
Jon Hallc6793552016-01-19 14:18:37 -08003550 except ( TypeError, ValueError ):
3551 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003552 return main.ERROR
3553 except pexpect.EOF:
3554 main.log.error( self.name + ": EOF exception found" )
3555 main.log.error( self.name + ": " + self.handle.before )
3556 main.cleanup()
3557 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003558 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003559 main.log.exception( self.name + ": Uncaught exception!" )
3560 main.cleanup()
3561 main.exit()
3562
Jon Hallfb760a02015-04-13 15:35:03 -07003563 def getCfg( self, component=None, propName=None, short=False,
3564 jsonFormat=True ):
3565 """
3566 Get configuration settings from onos cli
3567 Optional arguments:
3568 component - Optionally only list configurations for a specific
3569 component. If None, all components with configurations
3570 are displayed. Case Sensitive string.
3571 propName - If component is specified, propName option will show
3572 only this specific configuration from that component.
3573 Case Sensitive string.
3574 jsonFormat - Returns output as json. Note that this will override
3575 the short option
3576 short - Short, less verbose, version of configurations.
3577 This is overridden by the json option
3578 returns:
3579 Output from cli as a string or None on error
3580 """
3581 try:
3582 baseStr = "cfg"
3583 cmdStr = " get"
3584 componentStr = ""
3585 if component:
3586 componentStr += " " + component
3587 if propName:
3588 componentStr += " " + propName
3589 if jsonFormat:
3590 baseStr += " -j"
3591 elif short:
3592 baseStr += " -s"
3593 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003594 assert "Command not found:" not in output, output
3595 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003596 return output
3597 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003598 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003599 return None
3600 except TypeError:
3601 main.log.exception( self.name + ": Object not as expected" )
3602 return None
3603 except pexpect.EOF:
3604 main.log.error( self.name + ": EOF exception found" )
3605 main.log.error( self.name + ": " + self.handle.before )
3606 main.cleanup()
3607 main.exit()
3608 except Exception:
3609 main.log.exception( self.name + ": Uncaught exception!" )
3610 main.cleanup()
3611 main.exit()
3612
3613 def setCfg( self, component, propName, value=None, check=True ):
3614 """
3615 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003616 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003617 component - The case sensitive name of the component whose
3618 property is to be set
3619 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003620 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003621 value - The value to set the property to. If None, will unset the
3622 property and revert it to it's default value(if applicable)
3623 check - Boolean, Check whether the option was successfully set this
3624 only applies when a value is given.
3625 returns:
3626 main.TRUE on success or main.FALSE on failure. If check is False,
3627 will return main.TRUE unless there is an error
3628 """
3629 try:
3630 baseStr = "cfg"
3631 cmdStr = " set " + str( component ) + " " + str( propName )
3632 if value is not None:
3633 cmdStr += " " + str( value )
3634 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003635 assert "Command not found:" not in output, output
3636 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003637 if value and check:
3638 results = self.getCfg( component=str( component ),
3639 propName=str( propName ),
3640 jsonFormat=True )
3641 # Check if current value is what we just set
3642 try:
3643 jsonOutput = json.loads( results )
3644 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003645 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003646 main.log.exception( "Error parsing cfg output" )
3647 main.log.error( "output:" + repr( results ) )
3648 return main.FALSE
3649 if current == str( value ):
3650 return main.TRUE
3651 return main.FALSE
3652 return main.TRUE
3653 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003654 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003655 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003656 except ( TypeError, ValueError ):
3657 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003658 return main.FALSE
3659 except pexpect.EOF:
3660 main.log.error( self.name + ": EOF exception found" )
3661 main.log.error( self.name + ": " + self.handle.before )
3662 main.cleanup()
3663 main.exit()
3664 except Exception:
3665 main.log.exception( self.name + ": Uncaught exception!" )
3666 main.cleanup()
3667 main.exit()
3668
Jon Hall390696c2015-05-05 17:13:41 -07003669 def setTestAdd( self, setName, values ):
3670 """
3671 CLI command to add elements to a distributed set.
3672 Arguments:
3673 setName - The name of the set to add to.
3674 values - The value(s) to add to the set, space seperated.
3675 Example usages:
3676 setTestAdd( "set1", "a b c" )
3677 setTestAdd( "set2", "1" )
3678 returns:
3679 main.TRUE on success OR
3680 main.FALSE if elements were already in the set OR
3681 main.ERROR on error
3682 """
3683 try:
3684 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3685 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003686 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003687 try:
3688 # TODO: Maybe make this less hardcoded
3689 # ConsistentMap Exceptions
3690 assert "org.onosproject.store.service" not in output
3691 # Node not leader
3692 assert "java.lang.IllegalStateException" not in output
3693 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003694 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003695 "command: " + str( output ) )
3696 retryTime = 30 # Conservative time, given by Madan
3697 main.log.info( "Waiting " + str( retryTime ) +
3698 "seconds before retrying." )
3699 time.sleep( retryTime ) # Due to change in mastership
3700 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003701 assert "Error executing command" not in output
3702 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3703 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3704 main.log.info( self.name + ": " + output )
3705 if re.search( positiveMatch, output):
3706 return main.TRUE
3707 elif re.search( negativeMatch, output):
3708 return main.FALSE
3709 else:
3710 main.log.error( self.name + ": setTestAdd did not" +
3711 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003712 main.log.debug( self.name + " actual: " + repr( output ) )
3713 return main.ERROR
3714 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003715 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003716 return main.ERROR
3717 except TypeError:
3718 main.log.exception( self.name + ": Object not as expected" )
3719 return main.ERROR
3720 except pexpect.EOF:
3721 main.log.error( self.name + ": EOF exception found" )
3722 main.log.error( self.name + ": " + self.handle.before )
3723 main.cleanup()
3724 main.exit()
3725 except Exception:
3726 main.log.exception( self.name + ": Uncaught exception!" )
3727 main.cleanup()
3728 main.exit()
3729
3730 def setTestRemove( self, setName, values, clear=False, retain=False ):
3731 """
3732 CLI command to remove elements from a distributed set.
3733 Required arguments:
3734 setName - The name of the set to remove from.
3735 values - The value(s) to remove from the set, space seperated.
3736 Optional arguments:
3737 clear - Clear all elements from the set
3738 retain - Retain only the given values. (intersection of the
3739 original set and the given set)
3740 returns:
3741 main.TRUE on success OR
3742 main.FALSE if the set was not changed OR
3743 main.ERROR on error
3744 """
3745 try:
3746 cmdStr = "set-test-remove "
3747 if clear:
3748 cmdStr += "-c " + str( setName )
3749 elif retain:
3750 cmdStr += "-r " + str( setName ) + " " + str( values )
3751 else:
3752 cmdStr += str( setName ) + " " + str( values )
3753 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003754 try:
3755 # TODO: Maybe make this less hardcoded
3756 # ConsistentMap Exceptions
3757 assert "org.onosproject.store.service" not in output
3758 # Node not leader
3759 assert "java.lang.IllegalStateException" not in output
3760 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003761 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003762 "command: " + str( output ) )
3763 retryTime = 30 # Conservative time, given by Madan
3764 main.log.info( "Waiting " + str( retryTime ) +
3765 "seconds before retrying." )
3766 time.sleep( retryTime ) # Due to change in mastership
3767 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003768 assert "Command not found:" not in output, output
3769 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003770 main.log.info( self.name + ": " + output )
3771 if clear:
3772 pattern = "Set " + str( setName ) + " cleared"
3773 if re.search( pattern, output ):
3774 return main.TRUE
3775 elif retain:
3776 positivePattern = str( setName ) + " was pruned to contain " +\
3777 "only elements of set \[(.*)\]"
3778 negativePattern = str( setName ) + " was not changed by " +\
3779 "retaining only elements of the set " +\
3780 "\[(.*)\]"
3781 if re.search( positivePattern, output ):
3782 return main.TRUE
3783 elif re.search( negativePattern, output ):
3784 return main.FALSE
3785 else:
3786 positivePattern = "\[(.*)\] was removed from the set " +\
3787 str( setName )
3788 if ( len( values.split() ) == 1 ):
3789 negativePattern = "\[(.*)\] was not in set " +\
3790 str( setName )
3791 else:
3792 negativePattern = "No element of \[(.*)\] was in set " +\
3793 str( setName )
3794 if re.search( positivePattern, output ):
3795 return main.TRUE
3796 elif re.search( negativePattern, output ):
3797 return main.FALSE
3798 main.log.error( self.name + ": setTestRemove did not" +
3799 " match expected output" )
3800 main.log.debug( self.name + " expected: " + pattern )
3801 main.log.debug( self.name + " actual: " + repr( output ) )
3802 return main.ERROR
3803 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003804 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003805 return main.ERROR
3806 except TypeError:
3807 main.log.exception( self.name + ": Object not as expected" )
3808 return main.ERROR
3809 except pexpect.EOF:
3810 main.log.error( self.name + ": EOF exception found" )
3811 main.log.error( self.name + ": " + self.handle.before )
3812 main.cleanup()
3813 main.exit()
3814 except Exception:
3815 main.log.exception( self.name + ": Uncaught exception!" )
3816 main.cleanup()
3817 main.exit()
3818
3819 def setTestGet( self, setName, values="" ):
3820 """
3821 CLI command to get the elements in a distributed set.
3822 Required arguments:
3823 setName - The name of the set to remove from.
3824 Optional arguments:
3825 values - The value(s) to check if in the set, space seperated.
3826 returns:
3827 main.ERROR on error OR
3828 A list of elements in the set if no optional arguments are
3829 supplied OR
3830 A tuple containing the list then:
3831 main.FALSE if the given values are not in the set OR
3832 main.TRUE if the given values are in the set OR
3833 """
3834 try:
3835 values = str( values ).strip()
3836 setName = str( setName ).strip()
3837 length = len( values.split() )
3838 containsCheck = None
3839 # Patterns to match
3840 setPattern = "\[(.*)\]"
3841 pattern = "Items in set " + setName + ":\n" + setPattern
3842 containsTrue = "Set " + setName + " contains the value " + values
3843 containsFalse = "Set " + setName + " did not contain the value " +\
3844 values
3845 containsAllTrue = "Set " + setName + " contains the the subset " +\
3846 setPattern
3847 containsAllFalse = "Set " + setName + " did not contain the the" +\
3848 " subset " + setPattern
3849
3850 cmdStr = "set-test-get "
3851 cmdStr += setName + " " + values
3852 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003853 try:
3854 # TODO: Maybe make this less hardcoded
3855 # ConsistentMap Exceptions
3856 assert "org.onosproject.store.service" not in output
3857 # Node not leader
3858 assert "java.lang.IllegalStateException" not in output
3859 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003860 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003861 "command: " + str( output ) )
3862 retryTime = 30 # Conservative time, given by Madan
3863 main.log.info( "Waiting " + str( retryTime ) +
3864 "seconds before retrying." )
3865 time.sleep( retryTime ) # Due to change in mastership
3866 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003867 assert "Command not found:" not in output, output
3868 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003869 main.log.info( self.name + ": " + output )
3870
3871 if length == 0:
3872 match = re.search( pattern, output )
3873 else: # if given values
3874 if length == 1: # Contains output
3875 patternTrue = pattern + "\n" + containsTrue
3876 patternFalse = pattern + "\n" + containsFalse
3877 else: # ContainsAll output
3878 patternTrue = pattern + "\n" + containsAllTrue
3879 patternFalse = pattern + "\n" + containsAllFalse
3880 matchTrue = re.search( patternTrue, output )
3881 matchFalse = re.search( patternFalse, output )
3882 if matchTrue:
3883 containsCheck = main.TRUE
3884 match = matchTrue
3885 elif matchFalse:
3886 containsCheck = main.FALSE
3887 match = matchFalse
3888 else:
3889 main.log.error( self.name + " setTestGet did not match " +\
3890 "expected output" )
3891 main.log.debug( self.name + " expected: " + pattern )
3892 main.log.debug( self.name + " actual: " + repr( output ) )
3893 match = None
3894 if match:
3895 setMatch = match.group( 1 )
3896 if setMatch == '':
3897 setList = []
3898 else:
3899 setList = setMatch.split( ", " )
3900 if length > 0:
3901 return ( setList, containsCheck )
3902 else:
3903 return setList
3904 else: # no match
3905 main.log.error( self.name + ": setTestGet did not" +
3906 " match expected output" )
3907 main.log.debug( self.name + " expected: " + pattern )
3908 main.log.debug( self.name + " actual: " + repr( output ) )
3909 return main.ERROR
3910 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003911 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003912 return main.ERROR
3913 except TypeError:
3914 main.log.exception( self.name + ": Object not as expected" )
3915 return main.ERROR
3916 except pexpect.EOF:
3917 main.log.error( self.name + ": EOF exception found" )
3918 main.log.error( self.name + ": " + self.handle.before )
3919 main.cleanup()
3920 main.exit()
3921 except Exception:
3922 main.log.exception( self.name + ": Uncaught exception!" )
3923 main.cleanup()
3924 main.exit()
3925
3926 def setTestSize( self, setName ):
3927 """
3928 CLI command to get the elements in a distributed set.
3929 Required arguments:
3930 setName - The name of the set to remove from.
3931 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003932 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003933 None on error
3934 """
3935 try:
3936 # TODO: Should this check against the number of elements returned
3937 # and then return true/false based on that?
3938 setName = str( setName ).strip()
3939 # Patterns to match
3940 setPattern = "\[(.*)\]"
3941 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3942 setPattern
3943 cmdStr = "set-test-get -s "
3944 cmdStr += setName
3945 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003946 try:
3947 # TODO: Maybe make this less hardcoded
3948 # ConsistentMap Exceptions
3949 assert "org.onosproject.store.service" not in output
3950 # Node not leader
3951 assert "java.lang.IllegalStateException" not in output
3952 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003953 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003954 "command: " + str( output ) )
3955 retryTime = 30 # Conservative time, given by Madan
3956 main.log.info( "Waiting " + str( retryTime ) +
3957 "seconds before retrying." )
3958 time.sleep( retryTime ) # Due to change in mastership
3959 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003960 assert "Command not found:" not in output, output
3961 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003962 main.log.info( self.name + ": " + output )
3963 match = re.search( pattern, output )
3964 if match:
3965 setSize = int( match.group( 1 ) )
3966 setMatch = match.group( 2 )
3967 if len( setMatch.split() ) == setSize:
3968 main.log.info( "The size returned by " + self.name +
3969 " matches the number of elements in " +
3970 "the returned set" )
3971 else:
3972 main.log.error( "The size returned by " + self.name +
3973 " does not match the number of " +
3974 "elements in the returned set." )
3975 return setSize
3976 else: # no match
3977 main.log.error( self.name + ": setTestGet did not" +
3978 " match expected output" )
3979 main.log.debug( self.name + " expected: " + pattern )
3980 main.log.debug( self.name + " actual: " + repr( output ) )
3981 return None
3982 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003983 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003984 return None
Jon Hall390696c2015-05-05 17:13:41 -07003985 except TypeError:
3986 main.log.exception( self.name + ": Object not as expected" )
3987 return None
3988 except pexpect.EOF:
3989 main.log.error( self.name + ": EOF exception found" )
3990 main.log.error( self.name + ": " + self.handle.before )
3991 main.cleanup()
3992 main.exit()
3993 except Exception:
3994 main.log.exception( self.name + ": Uncaught exception!" )
3995 main.cleanup()
3996 main.exit()
3997
Jon Hall80daded2015-05-27 16:07:00 -07003998 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003999 """
4000 Command to list the various counters in the system.
4001 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004002 if jsonFormat, a string of the json object returned by the cli
4003 command
4004 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004005 None on error
4006 """
Jon Hall390696c2015-05-05 17:13:41 -07004007 try:
4008 counters = {}
4009 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004010 if jsonFormat:
4011 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004012 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004013 assert "Command not found:" not in output, output
4014 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004015 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004016 return output
Jon Hall390696c2015-05-05 17:13:41 -07004017 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004018 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004019 return None
Jon Hall390696c2015-05-05 17:13:41 -07004020 except TypeError:
4021 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004022 return None
Jon Hall390696c2015-05-05 17:13:41 -07004023 except pexpect.EOF:
4024 main.log.error( self.name + ": EOF exception found" )
4025 main.log.error( self.name + ": " + self.handle.before )
4026 main.cleanup()
4027 main.exit()
4028 except Exception:
4029 main.log.exception( self.name + ": Uncaught exception!" )
4030 main.cleanup()
4031 main.exit()
4032
Jon Halle1a3b752015-07-22 13:02:46 -07004033 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07004034 """
Jon Halle1a3b752015-07-22 13:02:46 -07004035 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004036 Required arguments:
4037 counter - The name of the counter to increment.
4038 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004039 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004040 inMemory - use in memory map for the counter
4041 returns:
4042 integer value of the counter or
4043 None on Error
4044 """
4045 try:
4046 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004047 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004048 cmdStr = "counter-test-increment "
4049 if inMemory:
4050 cmdStr += "-i "
4051 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004052 if delta != 1:
4053 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004054 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004055 try:
4056 # TODO: Maybe make this less hardcoded
4057 # ConsistentMap Exceptions
4058 assert "org.onosproject.store.service" not in output
4059 # Node not leader
4060 assert "java.lang.IllegalStateException" not in output
4061 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004062 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004063 "command: " + str( output ) )
4064 retryTime = 30 # Conservative time, given by Madan
4065 main.log.info( "Waiting " + str( retryTime ) +
4066 "seconds before retrying." )
4067 time.sleep( retryTime ) # Due to change in mastership
4068 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004069 assert "Command not found:" not in output, output
4070 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004071 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004072 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004073 match = re.search( pattern, output )
4074 if match:
4075 return int( match.group( 1 ) )
4076 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004077 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004078 " match expected output." )
4079 main.log.debug( self.name + " expected: " + pattern )
4080 main.log.debug( self.name + " actual: " + repr( output ) )
4081 return None
4082 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004083 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004084 return None
4085 except TypeError:
4086 main.log.exception( self.name + ": Object not as expected" )
4087 return None
4088 except pexpect.EOF:
4089 main.log.error( self.name + ": EOF exception found" )
4090 main.log.error( self.name + ": " + self.handle.before )
4091 main.cleanup()
4092 main.exit()
4093 except Exception:
4094 main.log.exception( self.name + ": Uncaught exception!" )
4095 main.cleanup()
4096 main.exit()
4097
Jon Halle1a3b752015-07-22 13:02:46 -07004098 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4099 """
4100 CLI command to get a distributed counter then add a delta to it.
4101 Required arguments:
4102 counter - The name of the counter to increment.
4103 Optional arguments:
4104 delta - The long to add to the counter
4105 inMemory - use in memory map for the counter
4106 returns:
4107 integer value of the counter or
4108 None on Error
4109 """
4110 try:
4111 counter = str( counter )
4112 delta = int( delta )
4113 cmdStr = "counter-test-increment -g "
4114 if inMemory:
4115 cmdStr += "-i "
4116 cmdStr += counter
4117 if delta != 1:
4118 cmdStr += " " + str( delta )
4119 output = self.sendline( cmdStr )
4120 try:
4121 # TODO: Maybe make this less hardcoded
4122 # ConsistentMap Exceptions
4123 assert "org.onosproject.store.service" not in output
4124 # Node not leader
4125 assert "java.lang.IllegalStateException" not in output
4126 except AssertionError:
4127 main.log.error( "Error in processing '" + cmdStr + "' " +
4128 "command: " + str( output ) )
4129 retryTime = 30 # Conservative time, given by Madan
4130 main.log.info( "Waiting " + str( retryTime ) +
4131 "seconds before retrying." )
4132 time.sleep( retryTime ) # Due to change in mastership
4133 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004134 assert "Command not found:" not in output, output
4135 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004136 main.log.info( self.name + ": " + output )
4137 pattern = counter + " was updated to (-?\d+)"
4138 match = re.search( pattern, output )
4139 if match:
4140 return int( match.group( 1 ) )
4141 else:
4142 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4143 " match expected output." )
4144 main.log.debug( self.name + " expected: " + pattern )
4145 main.log.debug( self.name + " actual: " + repr( output ) )
4146 return None
4147 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004148 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004149 return None
4150 except TypeError:
4151 main.log.exception( self.name + ": Object not as expected" )
4152 return None
4153 except pexpect.EOF:
4154 main.log.error( self.name + ": EOF exception found" )
4155 main.log.error( self.name + ": " + self.handle.before )
4156 main.cleanup()
4157 main.exit()
4158 except Exception:
4159 main.log.exception( self.name + ": Uncaught exception!" )
4160 main.cleanup()
4161 main.exit()
4162
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004163 def summary( self, jsonFormat=True ):
4164 """
4165 Description: Execute summary command in onos
4166 Returns: json object ( summary -j ), returns main.FALSE if there is
4167 no output
4168
4169 """
4170 try:
4171 cmdStr = "summary"
4172 if jsonFormat:
4173 cmdStr += " -j"
4174 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004175 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004176 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004177 if not handle:
4178 main.log.error( self.name + ": There is no output in " +
4179 "summary command" )
4180 return main.FALSE
4181 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004182 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004183 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004184 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004185 except TypeError:
4186 main.log.exception( self.name + ": Object not as expected" )
4187 return None
4188 except pexpect.EOF:
4189 main.log.error( self.name + ": EOF exception found" )
4190 main.log.error( self.name + ": " + self.handle.before )
4191 main.cleanup()
4192 main.exit()
4193 except Exception:
4194 main.log.exception( self.name + ": Uncaught exception!" )
4195 main.cleanup()
4196 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004197
4198 def transactionalMapGet( self, keyName, inMemory=False ):
4199 """
4200 CLI command to get the value of a key in a consistent map using
4201 transactions. This a test function and can only get keys from the
4202 test map hard coded into the cli command
4203 Required arguments:
4204 keyName - The name of the key to get
4205 Optional arguments:
4206 inMemory - use in memory map for the counter
4207 returns:
4208 The string value of the key or
4209 None on Error
4210 """
4211 try:
4212 keyName = str( keyName )
4213 cmdStr = "transactional-map-test-get "
4214 if inMemory:
4215 cmdStr += "-i "
4216 cmdStr += keyName
4217 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004218 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004219 try:
4220 # TODO: Maybe make this less hardcoded
4221 # ConsistentMap Exceptions
4222 assert "org.onosproject.store.service" not in output
4223 # Node not leader
4224 assert "java.lang.IllegalStateException" not in output
4225 except AssertionError:
4226 main.log.error( "Error in processing '" + cmdStr + "' " +
4227 "command: " + str( output ) )
4228 return None
4229 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4230 if "Key " + keyName + " not found." in output:
4231 return None
4232 else:
4233 match = re.search( pattern, output )
4234 if match:
4235 return match.groupdict()[ 'value' ]
4236 else:
4237 main.log.error( self.name + ": transactionlMapGet did not" +
4238 " match expected output." )
4239 main.log.debug( self.name + " expected: " + pattern )
4240 main.log.debug( self.name + " actual: " + repr( output ) )
4241 return None
Jon Hallc6793552016-01-19 14:18:37 -08004242 except AssertionError:
4243 main.log.exception( "" )
4244 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004245 except TypeError:
4246 main.log.exception( self.name + ": Object not as expected" )
4247 return None
4248 except pexpect.EOF:
4249 main.log.error( self.name + ": EOF exception found" )
4250 main.log.error( self.name + ": " + self.handle.before )
4251 main.cleanup()
4252 main.exit()
4253 except Exception:
4254 main.log.exception( self.name + ": Uncaught exception!" )
4255 main.cleanup()
4256 main.exit()
4257
4258 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4259 """
4260 CLI command to put a value into 'numKeys' number of keys in a
4261 consistent map using transactions. This a test function and can only
4262 put into keys named 'Key#' of the test map hard coded into the cli command
4263 Required arguments:
4264 numKeys - Number of keys to add the value to
4265 value - The string value to put into the keys
4266 Optional arguments:
4267 inMemory - use in memory map for the counter
4268 returns:
4269 A dictionary whose keys are the name of the keys put into the map
4270 and the values of the keys are dictionaries whose key-values are
4271 'value': value put into map and optionaly
4272 'oldValue': Previous value in the key or
4273 None on Error
4274
4275 Example output
4276 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4277 'Key2': {'value': 'Testing'} }
4278 """
4279 try:
4280 numKeys = str( numKeys )
4281 value = str( value )
4282 cmdStr = "transactional-map-test-put "
4283 if inMemory:
4284 cmdStr += "-i "
4285 cmdStr += numKeys + " " + value
4286 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004287 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004288 try:
4289 # TODO: Maybe make this less hardcoded
4290 # ConsistentMap Exceptions
4291 assert "org.onosproject.store.service" not in output
4292 # Node not leader
4293 assert "java.lang.IllegalStateException" not in output
4294 except AssertionError:
4295 main.log.error( "Error in processing '" + cmdStr + "' " +
4296 "command: " + str( output ) )
4297 return None
4298 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4299 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4300 results = {}
4301 for line in output.splitlines():
4302 new = re.search( newPattern, line )
4303 updated = re.search( updatedPattern, line )
4304 if new:
4305 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4306 elif updated:
4307 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004308 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004309 else:
4310 main.log.error( self.name + ": transactionlMapGet did not" +
4311 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004312 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4313 newPattern,
4314 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004315 main.log.debug( self.name + " actual: " + repr( output ) )
4316 return results
Jon Hallc6793552016-01-19 14:18:37 -08004317 except AssertionError:
4318 main.log.exception( "" )
4319 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004320 except TypeError:
4321 main.log.exception( self.name + ": Object not as expected" )
4322 return None
4323 except pexpect.EOF:
4324 main.log.error( self.name + ": EOF exception found" )
4325 main.log.error( self.name + ": " + self.handle.before )
4326 main.cleanup()
4327 main.exit()
4328 except Exception:
4329 main.log.exception( self.name + ": Uncaught exception!" )
4330 main.cleanup()
4331 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004332
acsmarsdaea66c2015-09-03 11:44:06 -07004333 def maps( self, jsonFormat=True ):
4334 """
4335 Description: Returns result of onos:maps
4336 Optional:
4337 * jsonFormat: enable json formatting of output
4338 """
4339 try:
4340 cmdStr = "maps"
4341 if jsonFormat:
4342 cmdStr += " -j"
4343 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004344 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004345 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004346 except AssertionError:
4347 main.log.exception( "" )
4348 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004349 except TypeError:
4350 main.log.exception( self.name + ": Object not as expected" )
4351 return None
4352 except pexpect.EOF:
4353 main.log.error( self.name + ": EOF exception found" )
4354 main.log.error( self.name + ": " + self.handle.before )
4355 main.cleanup()
4356 main.exit()
4357 except Exception:
4358 main.log.exception( self.name + ": Uncaught exception!" )
4359 main.cleanup()
4360 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004361
4362 def getSwController( self, uri, jsonFormat=True ):
4363 """
4364 Descrition: Gets the controller information from the device
4365 """
4366 try:
4367 cmd = "device-controllers "
4368 if jsonFormat:
4369 cmd += "-j "
4370 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004371 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004372 return response
Jon Hallc6793552016-01-19 14:18:37 -08004373 except AssertionError:
4374 main.log.exception( "" )
4375 return None
GlennRC050596c2015-11-18 17:06:41 -08004376 except TypeError:
4377 main.log.exception( self.name + ": Object not as expected" )
4378 return None
4379 except pexpect.EOF:
4380 main.log.error( self.name + ": EOF exception found" )
4381 main.log.error( self.name + ": " + self.handle.before )
4382 main.cleanup()
4383 main.exit()
4384 except Exception:
4385 main.log.exception( self.name + ": Uncaught exception!" )
4386 main.cleanup()
4387 main.exit()
4388
4389 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4390 """
4391 Descrition: sets the controller(s) for the specified device
4392
4393 Parameters:
4394 Required: uri - String: The uri of the device(switch).
4395 ip - String or List: The ip address of the controller.
4396 This parameter can be formed in a couple of different ways.
4397 VALID:
4398 10.0.0.1 - just the ip address
4399 tcp:10.0.0.1 - the protocol and the ip address
4400 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4401 so that you can add controllers with different
4402 protocols and ports
4403 INVALID:
4404 10.0.0.1:6653 - this is not supported by ONOS
4405
4406 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4407 port - The port number.
4408 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4409
4410 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4411 """
4412 try:
4413 cmd = "device-setcontrollers"
4414
4415 if jsonFormat:
4416 cmd += " -j"
4417 cmd += " " + uri
4418 if isinstance( ip, str ):
4419 ip = [ip]
4420 for item in ip:
4421 if ":" in item:
4422 sitem = item.split( ":" )
4423 if len(sitem) == 3:
4424 cmd += " " + item
4425 elif "." in sitem[1]:
4426 cmd += " {}:{}".format(item, port)
4427 else:
4428 main.log.error( "Malformed entry: " + item )
4429 raise TypeError
4430 else:
4431 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004432 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004433 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004434 if "Error" in response:
4435 main.log.error( response )
4436 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004437 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004438 except AssertionError:
4439 main.log.exception( "" )
4440 return None
GlennRC050596c2015-11-18 17:06:41 -08004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return main.FALSE
4444 except pexpect.EOF:
4445 main.log.error( self.name + ": EOF exception found" )
4446 main.log.error( self.name + ": " + self.handle.before )
4447 main.cleanup()
4448 main.exit()
4449 except Exception:
4450 main.log.exception( self.name + ": Uncaught exception!" )
4451 main.cleanup()
4452 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004453
4454 def removeDevice( self, device ):
4455 '''
4456 Description:
4457 Remove a device from ONOS by passing the uri of the device(s).
4458 Parameters:
4459 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4460 Returns:
4461 Returns main.FALSE if an exception is thrown or an error is present
4462 in the response. Otherwise, returns main.TRUE.
4463 NOTE:
4464 If a host cannot be removed, then this function will return main.FALSE
4465 '''
4466 try:
4467 if type( device ) is str:
4468 device = list( device )
4469
4470 for d in device:
4471 time.sleep( 1 )
4472 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004473 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004474 if "Error" in response:
4475 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4476 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004477 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004478 except AssertionError:
4479 main.log.exception( "" )
4480 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004481 except TypeError:
4482 main.log.exception( self.name + ": Object not as expected" )
4483 return main.FALSE
4484 except pexpect.EOF:
4485 main.log.error( self.name + ": EOF exception found" )
4486 main.log.error( self.name + ": " + self.handle.before )
4487 main.cleanup()
4488 main.exit()
4489 except Exception:
4490 main.log.exception( self.name + ": Uncaught exception!" )
4491 main.cleanup()
4492 main.exit()
4493
4494 def removeHost( self, host ):
4495 '''
4496 Description:
4497 Remove a host from ONOS by passing the id of the host(s)
4498 Parameters:
4499 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4500 Returns:
4501 Returns main.FALSE if an exception is thrown or an error is present
4502 in the response. Otherwise, returns main.TRUE.
4503 NOTE:
4504 If a host cannot be removed, then this function will return main.FALSE
4505 '''
4506 try:
4507 if type( host ) is str:
4508 host = list( host )
4509
4510 for h in host:
4511 time.sleep( 1 )
4512 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004513 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004514 if "Error" in response:
4515 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4516 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004517 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004518 except AssertionError:
4519 main.log.exception( "" )
4520 return None
GlennRC20fc6522015-12-23 23:26:57 -08004521 except TypeError:
4522 main.log.exception( self.name + ": Object not as expected" )
4523 return main.FALSE
4524 except pexpect.EOF:
4525 main.log.error( self.name + ": EOF exception found" )
4526 main.log.error( self.name + ": " + self.handle.before )
4527 main.cleanup()
4528 main.exit()
4529 except Exception:
4530 main.log.exception( self.name + ": Uncaught exception!" )
4531 main.cleanup()
4532 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004533
Jon Hallc6793552016-01-19 14:18:37 -08004534 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004535 '''
4536 Description:
4537 Bring link down or up in the null-provider.
4538 params:
4539 begin - (string) One end of a device or switch.
4540 end - (string) the other end of the device or switch
4541 returns:
4542 main.TRUE if no exceptions were thrown and no Errors are
4543 present in the resoponse. Otherwise, returns main.FALSE
4544 '''
4545 try:
Jon Hallc6793552016-01-19 14:18:37 -08004546 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004547 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004548 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004549 if "Error" in response or "Failure" in response:
4550 main.log.error( response )
4551 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004552 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004553 except AssertionError:
4554 main.log.exception( "" )
4555 return None
GlennRCed771242016-01-13 17:02:47 -08004556 except TypeError:
4557 main.log.exception( self.name + ": Object not as expected" )
4558 return main.FALSE
4559 except pexpect.EOF:
4560 main.log.error( self.name + ": EOF exception found" )
4561 main.log.error( self.name + ": " + self.handle.before )
4562 main.cleanup()
4563 main.exit()
4564 except Exception:
4565 main.log.exception( self.name + ": Uncaught exception!" )
4566 main.cleanup()
4567 main.exit()
4568