blob: 74ba41f29e55a6e0a1f0478196db6e9111e22273 [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" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1: # not in CLI
148 return main.TRUE
149 elif i == 3: # Timeout
150 return main.FALSE
151 else:
andrewonlab9627f432014-11-14 12:45:10 -0500152 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700158 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500159 main.cleanup()
160 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700161 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700162 main.log.error( self.name +
163 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 main.cleanup()
167 main.exit()
168
kelvin-onlabd3b64892015-01-20 13:26:24 -0800169 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab95ce8322014-10-13 14:12:04 -0400171 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800172
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800174 """
andrewonlab95ce8322014-10-13 14:12:04 -0400175 try:
176 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 main.cleanup()
179 main.exit()
180 else:
kelvin8ec71442015-01-15 16:57:00 -0800181 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800183 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400184 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800185 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800188 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800189 self.handle.sendline("")
190 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800191 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400195
196 return main.TRUE
197
Jon Halld4d4b372015-01-28 16:02:41 -0800198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400204 main.cleanup()
205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400208 main.cleanup()
209 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800210
pingping-lin57a56ce2015-05-20 16:43:48 -0700211 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800212 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
Jon Hallefbd9792015-03-05 16:11:36 -0800214 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800217 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800220
Hari Krishna25d42f72015-01-05 15:08:28 -0800221 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800223
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800226 """
You Wangf69ab392016-01-26 16:34:38 -0800227 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400228 try:
kelvin8ec71442015-01-15 16:57:00 -0800229 self.handle.sendline( "" )
230 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700231 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500232
233 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800234 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500235 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400236
kelvin8ec71442015-01-15 16:57:00 -0800237 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800239 i = self.handle.expect( [
240 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700241 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400242
243 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800245 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800246 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800247 "config:property-set -p org.apache.karaf.shell\
248 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800249 karafTimeout )
250 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400253 return main.TRUE
254 else:
kelvin8ec71442015-01-15 16:57:00 -0800255 # If failed, send ctrl+c to process and try again
256 main.log.info( "Starting CLI failed. Retrying..." )
257 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800259 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
260 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400261 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800263 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800264 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 "config:property-set -p org.apache.karaf.shell\
267 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800268 karafTimeout )
269 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800270 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800271 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400272 return main.TRUE
273 else:
kelvin8ec71442015-01-15 16:57:00 -0800274 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400276 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400277
Jon Halld4d4b372015-01-28 16:02:41 -0800278 except TypeError:
279 main.log.exception( self.name + ": Object not as expected" )
280 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400281 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800282 main.log.error( self.name + ": EOF exception found" )
283 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400284 main.cleanup()
285 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800286 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800287 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400288 main.cleanup()
289 main.exit()
290
Jon Hallefbd9792015-03-05 16:11:36 -0800291 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800292 """
293 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800294 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800295 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800296 Available level: DEBUG, TRACE, INFO, WARN, ERROR
297 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800298 """
299 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800300 lvlStr = ""
301 if level:
302 lvlStr = "--level=" + level
303
kelvin-onlab9f541032015-02-04 16:19:53 -0800304 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800305 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700306 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800307 main.log.error( self.name + ": onos cli session closed. ")
308 if self.onosIp:
309 main.log.warn( "Trying to reconnect " + self.onosIp )
310 reconnectResult = self.startOnosCli( self.onosIp )
311 if reconnectResult:
312 main.log.info( self.name + ": onos cli session reconnected." )
313 else:
314 main.log.error( self.name + ": reconnection failed." )
315 main.cleanup()
316 main.exit()
317 else:
318 main.cleanup()
319 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700320 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700321 self.handle.sendline( "" )
322 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800323 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700324 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800325 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800326
kelvin-onlab9f541032015-02-04 16:19:53 -0800327 response = self.handle.before
328 if re.search( "Error", response ):
329 return main.FALSE
330 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700331 except pexpect.TIMEOUT:
332 main.log.exception( self.name + ": TIMEOUT exception found" )
333 main.cleanup()
334 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800335 except pexpect.EOF:
336 main.log.error( self.name + ": EOF exception found" )
337 main.log.error( self.name + ": " + self.handle.before )
338 main.cleanup()
339 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800340 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800341 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400342 main.cleanup()
343 main.exit()
344
GlennRCed771242016-01-13 17:02:47 -0800345 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800346 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800347 Send a completely user specified string to
348 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400349 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800350
andrewonlaba18f6bf2014-10-13 19:31:54 -0400351 Warning: There are no sanity checking to commands
352 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800353
kelvin8ec71442015-01-15 16:57:00 -0800354 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400355 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800356 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
357 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800359 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800360 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800361 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800362 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
363 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700365 main.log.debug( self.name + ": Raw output" )
366 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700367
368 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800369 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800370 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700372 main.log.debug( self.name + ": ansiEscape output" )
373 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700374
kelvin-onlabfb521662015-02-27 09:52:40 -0800375 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800376 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700377 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700378 main.log.debug( self.name + ": Removed extra returns " +
379 "from output" )
380 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700381
382 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800383 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700384 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700385 main.log.debug( self.name + ": parsed and stripped output" )
386 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700387
Jon Hall63604932015-02-26 17:09:50 -0800388 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700389 output = response.split( cmdStr.strip(), 1 )
390 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700391 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700392 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700393 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800394 output = output[1].strip()
395 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800396 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800397 return output
GlennRCed771242016-01-13 17:02:47 -0800398 except pexpect.TIMEOUT:
399 main.log.error( self.name + ":ONOS timeout" )
400 if debug:
401 main.log.debug( self.handle.before )
402 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700403 except IndexError:
404 main.log.exception( self.name + ": Object not as expected" )
405 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400412 main.cleanup()
413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400416 main.cleanup()
417 main.exit()
418
kelvin8ec71442015-01-15 16:57:00 -0800419 # IMPORTANT NOTE:
420 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 # the cli command changing 'a:b' with 'aB'.
422 # Ex ) onos:topology > onosTopology
423 # onos:links > onosLinks
424 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800425
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800427 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400428 Adds a new cluster node by ID and address information.
429 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 * nodeId
431 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800434 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800436 cmdStr = "add-node " + str( nodeId ) + " " +\
437 str( ONOSIp ) + " " + str( tcpPort )
438 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800439 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800440 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( "Error in adding node" )
442 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800443 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800445 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800447 except AssertionError:
448 main.log.exception( "" )
449 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800450 except TypeError:
451 main.log.exception( self.name + ": Object not as expected" )
452 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( self.name + ": EOF exception found" )
455 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400456 main.cleanup()
457 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800459 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400460 main.cleanup()
461 main.exit()
462
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
andrewonlab86dc3082014-10-13 18:18:38 -0400465 Removes a cluster by ID
466 Issues command: 'remove-node [<node-id>]'
467 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800469 """
andrewonlab86dc3082014-10-13 18:18:38 -0400470 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400471
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700473 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800474 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700475 if re.search( "Error", handle ):
476 main.log.error( "Error in removing node" )
477 main.log.error( handle )
478 return main.FALSE
479 else:
480 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800481 except AssertionError:
482 main.log.exception( "" )
483 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800484 except TypeError:
485 main.log.exception( self.name + ": Object not as expected" )
486 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400487 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800488 main.log.error( self.name + ": EOF exception found" )
489 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400490 main.cleanup()
491 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800493 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400494 main.cleanup()
495 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400496
Jon Hall61282e32015-03-19 11:34:11 -0700497 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800498 """
andrewonlab7c211572014-10-15 16:45:20 -0400499 List the nodes currently visible
500 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700501 Optional argument:
502 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlab7c211572014-10-15 16:45:20 -0400504 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700506 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 cmdStr += " -j"
508 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800509 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700510 return output
Jon Hallc6793552016-01-19 14:18:37 -0800511 except AssertionError:
512 main.log.exception( "" )
513 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800514 except TypeError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
andrewonlab7c211572014-10-15 16:45:20 -0400517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400520 main.cleanup()
521 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800522 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800523 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400524 main.cleanup()
525 main.exit()
526
kelvin8ec71442015-01-15 16:57:00 -0800527 def topology( self ):
528 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700529 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700530 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700531 Return:
532 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800533 """
andrewonlab95ce8322014-10-13 14:12:04 -0400534 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700535 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800537 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400539 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800540 except AssertionError:
541 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800542 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800543 except TypeError:
544 main.log.exception( self.name + ": Object not as expected" )
545 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400546 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 main.cleanup()
550 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800551 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800552 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 main.cleanup()
554 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800555
jenkins7ead5a82015-03-13 10:28:21 -0700556 def deviceRemove( self, deviceId ):
557 """
558 Removes particular device from storage
559
560 TODO: refactor this function
561 """
562 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700563 cmdStr = "device-remove " + str( deviceId )
564 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 if re.search( "Error", handle ):
567 main.log.error( "Error in removing device" )
568 main.log.error( handle )
569 return main.FALSE
570 else:
571 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800572 except AssertionError:
573 main.log.exception( "" )
574 return None
jenkins7ead5a82015-03-13 10:28:21 -0700575 except TypeError:
576 main.log.exception( self.name + ": Object not as expected" )
577 return None
578 except pexpect.EOF:
579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
581 main.cleanup()
582 main.exit()
583 except Exception:
584 main.log.exception( self.name + ": Uncaught exception!" )
585 main.cleanup()
586 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700587
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800589 """
Jon Hall7b02d952014-10-17 20:14:54 -0400590 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800593 """
andrewonlab86dc3082014-10-13 18:18:38 -0400594 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 cmdStr += " -j"
598 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800599 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700600 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800601 except AssertionError:
602 main.log.exception( "" )
603 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800604 except TypeError:
605 main.log.exception( self.name + ": Object not as expected" )
606 return None
andrewonlab7c211572014-10-15 16:45:20 -0400607 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800608 main.log.error( self.name + ": EOF exception found" )
609 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400610 main.cleanup()
611 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800612 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800613 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800619 This balances the devices across all controllers
620 by issuing command: 'onos> onos:balance-masters'
621 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800623 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700625 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800626 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 if re.search( "Error", handle ):
628 main.log.error( "Error in balancing masters" )
629 main.log.error( handle )
630 return main.FALSE
631 else:
632 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800633 except AssertionError:
634 main.log.exception( "" )
635 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 main.cleanup()
647 main.exit()
648
Jon Hallc6793552016-01-19 14:18:37 -0800649 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700650 """
651 Returns the output of the masters command.
652 Optional argument:
653 * jsonFormat - boolean indicating if you want output in json
654 """
655 try:
656 cmdStr = "onos:masters"
657 if jsonFormat:
658 cmdStr += " -j"
659 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800660 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700661 return output
Jon Hallc6793552016-01-19 14:18:37 -0800662 except AssertionError:
663 main.log.exception( "" )
664 return None
acsmars24950022015-07-30 18:00:43 -0700665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
668 except pexpect.EOF:
669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
671 main.cleanup()
672 main.exit()
673 except Exception:
674 main.log.exception( self.name + ": Uncaught exception!" )
675 main.cleanup()
676 main.exit()
677
Jon Hallc6793552016-01-19 14:18:37 -0800678 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700679 """
680 Uses the master command to check that the devices' leadership
681 is evenly divided
682
683 Dependencies: checkMasters() and summary()
684
685 Returns main.True if the devices are balanced
686 Returns main.False if the devices are unbalanced
687 Exits on Exception
688 Returns None on TypeError
689 """
690 try:
Jon Hallc6793552016-01-19 14:18:37 -0800691 summaryOutput = self.summary()
692 totalDevices = json.loads( summaryOutput )[ "devices" ]
693 except ( TypeError, ValueError ):
694 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
695 return None
696 try:
acsmars24950022015-07-30 18:00:43 -0700697 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800698 mastersOutput = self.checkMasters()
699 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700700 first = masters[ 0 ][ "size" ]
701 for master in masters:
702 totalOwnedDevices += master[ "size" ]
703 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
704 main.log.error( "Mastership not balanced" )
705 main.log.info( "\n" + self.checkMasters( False ) )
706 return main.FALSE
707 main.log.info( "Mastership balanced between " \
708 + str( len(masters) ) + " masters" )
709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800710 except ( TypeError, ValueError ):
711 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700712 return None
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
716 main.cleanup()
717 main.exit()
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
720 main.cleanup()
721 main.exit()
722
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800724 """
Jon Halle8217482014-10-17 13:49:14 -0400725 Lists all core links
726 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800728 """
Jon Halle8217482014-10-17 13:49:14 -0400729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 cmdStr += " -j"
733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800736 except AssertionError:
737 main.log.exception( "" )
738 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800739 except TypeError:
740 main.log.exception( self.name + ": Object not as expected" )
741 return None
Jon Halle8217482014-10-17 13:49:14 -0400742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800743 main.log.error( self.name + ": EOF exception found" )
744 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400745 main.cleanup()
746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800748 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Jon Halle8217482014-10-17 13:49:14 -0400754 Lists all ports
755 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Jon Halle8217482014-10-17 13:49:14 -0400758 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700759 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700761 cmdStr += " -j"
762 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800763 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700764 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800765 except AssertionError:
766 main.log.exception( "" )
767 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800768 except TypeError:
769 main.log.exception( self.name + ": Object not as expected" )
770 return None
Jon Halle8217482014-10-17 13:49:14 -0400771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400774 main.cleanup()
775 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800776 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800777 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400778 main.cleanup()
779 main.exit()
780
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800782 """
Jon Hall983a1702014-10-28 18:44:22 -0400783 Lists all devices and the controllers with roles assigned to them
784 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800786 """
andrewonlab7c211572014-10-15 16:45:20 -0400787 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700788 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700790 cmdStr += " -j"
791 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800792 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800794 except AssertionError:
795 main.log.exception( "" )
796 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800797 except TypeError:
798 main.log.exception( self.name + ": Object not as expected" )
799 return None
Jon Hall983a1702014-10-28 18:44:22 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400803 main.cleanup()
804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800805 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800806 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400807 main.cleanup()
808 main.exit()
809
kelvin-onlabd3b64892015-01-20 13:26:24 -0800810 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800811 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800812 Given the a string containing the json representation of the "roles"
813 cli command and a partial or whole device id, returns a json object
814 containing the roles output for the first device whose id contains
815 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400816
817 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800818 A dict of the role assignments for the given device or
819 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800820 """
Jon Hall983a1702014-10-28 18:44:22 -0400821 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400823 return None
824 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 rawRoles = self.roles()
826 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800827 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800829 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800830 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400831 return device
832 return None
Jon Hallc6793552016-01-19 14:18:37 -0800833 except ( TypeError, ValueError ):
834 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800835 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400839 main.cleanup()
840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800842 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400843 main.cleanup()
844 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800845
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Hall94fd0472014-12-08 11:52:42 -0800848 Iterates through each device and checks if there is a master assigned
849 Returns: main.TRUE if each device has a master
850 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall94fd0472014-12-08 11:52:42 -0800852 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 rawRoles = self.roles()
854 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800855 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800857 # print device
858 if device[ 'master' ] == "none":
859 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800860 return main.FALSE
861 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800862 except ( TypeError, ValueError ):
863 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800864 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800868 main.cleanup()
869 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800870 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800871 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800872 main.cleanup()
873 main.exit()
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400877 Returns string of paths, and the cost.
878 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800879 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400880 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
882 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800883 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800884 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800885 main.log.error( "Error in getting paths" )
886 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400887 else:
kelvin8ec71442015-01-15 16:57:00 -0800888 path = handle.split( ";" )[ 0 ]
889 cost = handle.split( ";" )[ 1 ]
890 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800891 except AssertionError:
892 main.log.exception( "" )
893 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800894 except TypeError:
895 main.log.exception( self.name + ": Object not as expected" )
896 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( self.name + ": EOF exception found" )
899 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400900 main.cleanup()
901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400904 main.cleanup()
905 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Hallffb386d2014-11-21 13:43:38 -0800909 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400910 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800912 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400913 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700914 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 cmdStr += " -j"
917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800918 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800919 try:
920 # TODO: Maybe make this less hardcoded
921 # ConsistentMap Exceptions
922 assert "org.onosproject.store.service" not in handle
923 # Node not leader
924 assert "java.lang.IllegalStateException" not in handle
925 except AssertionError:
926 main.log.error( "Error in processing '" + cmdStr + "' " +
927 "command: " + str( handle ) )
928 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400939 main.cleanup()
940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400943 main.cleanup()
944 main.exit()
945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800947 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400948 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800949
Jon Hallefbd9792015-03-05 16:11:36 -0800950 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800951 partial mac address
952
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800954 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400955 try:
kelvin8ec71442015-01-15 16:57:00 -0800956 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400957 return None
958 else:
959 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 rawHosts = self.hosts()
961 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800962 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800964 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800965 if not host:
966 pass
967 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400968 return host
969 return None
Jon Hallc6793552016-01-19 14:18:37 -0800970 except ( TypeError, ValueError ):
971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800972 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400973 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400976 main.cleanup()
977 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800979 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400980 main.cleanup()
981 main.exit()
982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800984 """
985 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400986 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800987
andrewonlab3f0a4af2014-10-17 12:25:14 -0400988 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400990 IMPORTANT:
991 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800992 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400993 Furthermore, it assumes that value of VLAN is '-1'
994 Description:
kelvin8ec71442015-01-15 16:57:00 -0800995 Converts mininet hosts ( h1, h2, h3... ) into
996 ONOS format ( 00:00:00:00:00:01/-1 , ... )
997 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001002 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 hostHex = hex( int( host ) ).zfill( 12 )
1004 hostHex = str( hostHex ).replace( 'x', '0' )
1005 i = iter( str( hostHex ) )
1006 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1007 hostHex = hostHex + "/-1"
1008 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001009
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001011
Jon Halld4d4b372015-01-28 16:02:41 -08001012 except TypeError:
1013 main.log.exception( self.name + ": Object not as expected" )
1014 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001015 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001018 main.cleanup()
1019 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001020 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001021 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001022 main.cleanup()
1023 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001024
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001026 """
andrewonlabe6745342014-10-17 14:29:13 -04001027 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 * hostIdOne: ONOS host id for host1
1029 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001030 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001031 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001032 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001033 Returns:
1034 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlabe6745342014-10-17 14:29:13 -04001036 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1038 " " + str( hostIdTwo )
1039 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001040 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001041 if re.search( "Error", handle ):
1042 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001043 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001044 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001045 else:
1046 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001047 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1048 match = re.search('id=0x([\da-f]+),', handle)
1049 if match:
1050 return match.group()[3:-1]
1051 else:
1052 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001053 main.log.debug( "Response from ONOS was: " +
1054 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001055 return None
Jon Hallc6793552016-01-19 14:18:37 -08001056 except AssertionError:
1057 main.log.exception( "" )
1058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
andrewonlabe6745342014-10-17 14:29:13 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab7b31d232014-10-24 13:31:47 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001077 Optional:
1078 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001079 Description:
1080 Adds an optical intent by specifying an ingress and egress device
1081 Returns:
1082 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001083 """
andrewonlab7b31d232014-10-24 13:31:47 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1086 " " + str( egressDevice )
1087 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001088 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001089 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 main.log.error( "Error in adding Optical intent" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001094 main.log.info( "Optical intent installed between " +
1095 str( ingressDevice ) + " and " +
1096 str( egressDevice ) )
1097 match = re.search('id=0x([\da-f]+),', handle)
1098 if match:
1099 return match.group()[3:-1]
1100 else:
1101 main.log.error( "Error, intent ID not found" )
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except AssertionError:
1104 main.log.exception( "" )
1105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001106 except TypeError:
1107 main.log.exception( self.name + ": Object not as expected" )
1108 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( self.name + ": EOF exception found" )
1111 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001112 main.cleanup()
1113 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001114 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001115 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001116 main.cleanup()
1117 main.exit()
1118
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001120 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 ingressDevice,
1122 egressDevice,
1123 portIngress="",
1124 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001125 ethType="",
1126 ethSrc="",
1127 ethDst="",
1128 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001130 ipProto="",
1131 ipSrc="",
1132 ipDst="",
1133 tcpSrc="",
1134 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001136 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 * ingressDevice: device id of ingress device
1138 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001139 Optional:
1140 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001141 * ethSrc: specify ethSrc ( i.e. src mac addr )
1142 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001143 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001145 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001146 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001147 * ipSrc: specify ip source address
1148 * ipDst: specify ip destination address
1149 * tcpSrc: specify tcp source port
1150 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001151 Description:
kelvin8ec71442015-01-15 16:57:00 -08001152 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001153 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001154 Returns:
1155 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001156
Jon Halle3f39ff2015-01-13 11:50:53 -08001157 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001158 options developers provide for point-to-point
1159 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001161 try:
kelvin8ec71442015-01-15 16:57:00 -08001162 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001163 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001165 and not ipProto and not ipSrc and not ipDst \
1166 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001167 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001168
andrewonlab289e4b72014-10-21 21:24:18 -04001169 else:
andrewonlab36af3822014-11-18 17:48:18 -05001170 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001171
andrewonlab0c0a6772014-10-22 12:31:18 -04001172 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001173 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001174 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --ethSrc " + str( ethSrc )
1176 if ethDst:
1177 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001178 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 cmd += " --lambda "
1182 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001184 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001186 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001188 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001190 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001191 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001192
kelvin8ec71442015-01-15 16:57:00 -08001193 # Check whether the user appended the port
1194 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if "/" in ingressDevice:
1196 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001197 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001199 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001200 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001201 # Would it make sense to throw an exception and exit
1202 # the test?
1203 return None
andrewonlab36af3822014-11-18 17:48:18 -05001204
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 str( ingressDevice ) + "/" +\
1207 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001208
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if "/" in egressDevice:
1210 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001211 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001213 main.log.error( "You must specify the egress port" )
1214 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001215
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001217 str( egressDevice ) + "/" +\
1218 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001219
kelvin-onlab898a6c62015-01-16 14:13:53 -08001220 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001222 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001225 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 # TODO: print out all the options in this message?
1228 main.log.info( "Point-to-point intent installed between " +
1229 str( ingressDevice ) + " and " +
1230 str( egressDevice ) )
1231 match = re.search('id=0x([\da-f]+),', handle)
1232 if match:
1233 return match.group()[3:-1]
1234 else:
1235 main.log.error( "Error, intent ID not found" )
1236 return None
Jon Hallc6793552016-01-19 14:18:37 -08001237 except AssertionError:
1238 main.log.exception( "" )
1239 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001240 except TypeError:
1241 main.log.exception( self.name + ": Object not as expected" )
1242 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.error( self.name + ": EOF exception found" )
1245 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001246 main.cleanup()
1247 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001248 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001249 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001250 main.cleanup()
1251 main.exit()
1252
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001254 self,
shahshreyac2f97072015-03-19 17:04:29 -07001255 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001257 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 ethType="",
1260 ethSrc="",
1261 ethDst="",
1262 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 ipProto="",
1265 ipSrc="",
1266 ipDst="",
1267 tcpSrc="",
1268 tcpDst="",
1269 setEthSrc="",
1270 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001271 """
shahshreyad0c80432014-12-04 16:56:05 -08001272 Note:
shahshreya70622b12015-03-19 17:19:00 -07001273 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001274 is same. That is, all ingress devices include port numbers
1275 with a "/" or all ingress devices could specify device
1276 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001277 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001278 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001279 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
1293 * setEthSrc: action to Rewrite Source MAC Address
1294 * setEthDst: action to Rewrite Destination MAC Address
1295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001302 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
shahshreyad0c80432014-12-04 16:56:05 -08001305 try:
kelvin8ec71442015-01-15 16:57:00 -08001306 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001307 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001309 and not ipProto and not ipSrc and not ipDst\
1310 and not tcpSrc and not tcpDst and not setEthSrc\
1311 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001312 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001313
1314 else:
1315 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001316
shahshreyad0c80432014-12-04 16:56:05 -08001317 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001318 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001319 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001320 cmd += " --ethSrc " + str( ethSrc )
1321 if ethDst:
1322 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001323 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001324 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001326 cmd += " --lambda "
1327 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001329 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001330 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001331 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001333 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001334 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001335 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001336 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001337 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001339 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001341
kelvin8ec71442015-01-15 16:57:00 -08001342 # Check whether the user appended the port
1343 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001344
1345 if portIngressList is None:
1346 for ingressDevice in ingressDeviceList:
1347 if "/" in ingressDevice:
1348 cmd += " " + str( ingressDevice )
1349 else:
1350 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001351 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001352 # TODO: perhaps more meaningful return
1353 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001354 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001355 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001356 for ingressDevice, portIngress in zip( ingressDeviceList,
1357 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001358 cmd += " " + \
1359 str( ingressDevice ) + "/" +\
1360 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001361 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001362 main.log.error( "Device list and port list does not " +
1363 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001364 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if "/" in egressDevice:
1366 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001367 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.error( "You must specify " +
1370 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001371 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001372
kelvin8ec71442015-01-15 16:57:00 -08001373 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 str( egressDevice ) + "/" +\
1375 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001377 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001379 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 main.log.error( "Error in adding multipoint-to-singlepoint " +
1381 "intent" )
1382 return None
shahshreyad0c80432014-12-04 16:56:05 -08001383 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001384 match = re.search('id=0x([\da-f]+),', handle)
1385 if match:
1386 return match.group()[3:-1]
1387 else:
1388 main.log.error( "Error, intent ID not found" )
1389 return None
Jon Hallc6793552016-01-19 14:18:37 -08001390 except AssertionError:
1391 main.log.exception( "" )
1392 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001393 except TypeError:
1394 main.log.exception( self.name + ": Object not as expected" )
1395 return None
1396 except pexpect.EOF:
1397 main.log.error( self.name + ": EOF exception found" )
1398 main.log.error( self.name + ": " + self.handle.before )
1399 main.cleanup()
1400 main.exit()
1401 except Exception:
1402 main.log.exception( self.name + ": Uncaught exception!" )
1403 main.cleanup()
1404 main.exit()
1405
1406 def addSinglepointToMultipointIntent(
1407 self,
1408 ingressDevice,
1409 egressDeviceList,
1410 portIngress="",
1411 portEgressList=None,
1412 ethType="",
1413 ethSrc="",
1414 ethDst="",
1415 bandwidth="",
1416 lambdaAlloc=False,
1417 ipProto="",
1418 ipSrc="",
1419 ipDst="",
1420 tcpSrc="",
1421 tcpDst="",
1422 setEthSrc="",
1423 setEthDst="" ):
1424 """
1425 Note:
1426 This function assumes the format of all egress devices
1427 is same. That is, all egress devices include port numbers
1428 with a "/" or all egress devices could specify device
1429 ids and port numbers seperately.
1430 Required:
1431 * EgressDeviceList: List of device ids of egress device
1432 ( Atleast 2 eress devices required in the list )
1433 * ingressDevice: device id of ingress device
1434 Optional:
1435 * ethType: specify ethType
1436 * ethSrc: specify ethSrc ( i.e. src mac addr )
1437 * ethDst: specify ethDst ( i.e. dst mac addr )
1438 * bandwidth: specify bandwidth capacity of link
1439 * lambdaAlloc: if True, intent will allocate lambda
1440 for the specified intent
1441 * ipProto: specify ip protocol
1442 * ipSrc: specify ip source address
1443 * ipDst: specify ip destination address
1444 * tcpSrc: specify tcp source port
1445 * tcpDst: specify tcp destination port
1446 * setEthSrc: action to Rewrite Source MAC Address
1447 * setEthDst: action to Rewrite Destination MAC Address
1448 Description:
1449 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1450 specifying device id's and optional fields
1451 Returns:
1452 A string of the intent id or None on error
1453
1454 NOTE: This function may change depending on the
1455 options developers provide for singlepoint-to-multipoint
1456 intent via cli
1457 """
1458 try:
1459 # If there are no optional arguments
1460 if not ethType and not ethSrc and not ethDst\
1461 and not bandwidth and not lambdaAlloc\
1462 and not ipProto and not ipSrc and not ipDst\
1463 and not tcpSrc and not tcpDst and not setEthSrc\
1464 and not setEthDst:
1465 cmd = "add-single-to-multi-intent"
1466
1467 else:
1468 cmd = "add-single-to-multi-intent"
1469
1470 if ethType:
1471 cmd += " --ethType " + str( ethType )
1472 if ethSrc:
1473 cmd += " --ethSrc " + str( ethSrc )
1474 if ethDst:
1475 cmd += " --ethDst " + str( ethDst )
1476 if bandwidth:
1477 cmd += " --bandwidth " + str( bandwidth )
1478 if lambdaAlloc:
1479 cmd += " --lambda "
1480 if ipProto:
1481 cmd += " --ipProto " + str( ipProto )
1482 if ipSrc:
1483 cmd += " --ipSrc " + str( ipSrc )
1484 if ipDst:
1485 cmd += " --ipDst " + str( ipDst )
1486 if tcpSrc:
1487 cmd += " --tcpSrc " + str( tcpSrc )
1488 if tcpDst:
1489 cmd += " --tcpDst " + str( tcpDst )
1490 if setEthSrc:
1491 cmd += " --setEthSrc " + str( setEthSrc )
1492 if setEthDst:
1493 cmd += " --setEthDst " + str( setEthDst )
1494
1495 # Check whether the user appended the port
1496 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001497
kelvin-onlabb9408212015-04-01 13:34:04 -07001498 if "/" in ingressDevice:
1499 cmd += " " + str( ingressDevice )
1500 else:
1501 if not portIngress:
1502 main.log.error( "You must specify " +
1503 "the Ingress port" )
1504 return main.FALSE
1505
1506 cmd += " " +\
1507 str( ingressDevice ) + "/" +\
1508 str( portIngress )
1509
1510 if portEgressList is None:
1511 for egressDevice in egressDeviceList:
1512 if "/" in egressDevice:
1513 cmd += " " + str( egressDevice )
1514 else:
1515 main.log.error( "You must specify " +
1516 "the egress port" )
1517 # TODO: perhaps more meaningful return
1518 return main.FALSE
1519 else:
1520 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001521 for egressDevice, portEgress in zip( egressDeviceList,
1522 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001523 cmd += " " + \
1524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001526 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001527 main.log.error( "Device list and port list does not " +
1528 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001529 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001530 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001531 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001532 # If error, return error message
1533 if re.search( "Error", handle ):
1534 main.log.error( "Error in adding singlepoint-to-multipoint " +
1535 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001536 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001537 else:
1538 match = re.search('id=0x([\da-f]+),', handle)
1539 if match:
1540 return match.group()[3:-1]
1541 else:
1542 main.log.error( "Error, intent ID not found" )
1543 return None
Jon Hallc6793552016-01-19 14:18:37 -08001544 except AssertionError:
1545 main.log.exception( "" )
1546 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001547 except TypeError:
1548 main.log.exception( self.name + ": Object not as expected" )
1549 return None
shahshreyad0c80432014-12-04 16:56:05 -08001550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001551 main.log.error( self.name + ": EOF exception found" )
1552 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001553 main.cleanup()
1554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001556 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001557 main.cleanup()
1558 main.exit()
1559
Hari Krishna9e232602015-04-13 17:29:08 -07001560 def addMplsIntent(
1561 self,
1562 ingressDevice,
1563 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001564 ingressPort="",
1565 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001566 ethType="",
1567 ethSrc="",
1568 ethDst="",
1569 bandwidth="",
1570 lambdaAlloc=False,
1571 ipProto="",
1572 ipSrc="",
1573 ipDst="",
1574 tcpSrc="",
1575 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001576 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001577 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001578 priority=""):
1579 """
1580 Required:
1581 * ingressDevice: device id of ingress device
1582 * egressDevice: device id of egress device
1583 Optional:
1584 * ethType: specify ethType
1585 * ethSrc: specify ethSrc ( i.e. src mac addr )
1586 * ethDst: specify ethDst ( i.e. dst mac addr )
1587 * bandwidth: specify bandwidth capacity of link
1588 * lambdaAlloc: if True, intent will allocate lambda
1589 for the specified intent
1590 * ipProto: specify ip protocol
1591 * ipSrc: specify ip source address
1592 * ipDst: specify ip destination address
1593 * tcpSrc: specify tcp source port
1594 * tcpDst: specify tcp destination port
1595 * ingressLabel: Ingress MPLS label
1596 * egressLabel: Egress MPLS label
1597 Description:
1598 Adds MPLS intent by
1599 specifying device id's and optional fields
1600 Returns:
1601 A string of the intent id or None on error
1602
1603 NOTE: This function may change depending on the
1604 options developers provide for MPLS
1605 intent via cli
1606 """
1607 try:
1608 # If there are no optional arguments
1609 if not ethType and not ethSrc and not ethDst\
1610 and not bandwidth and not lambdaAlloc \
1611 and not ipProto and not ipSrc and not ipDst \
1612 and not tcpSrc and not tcpDst and not ingressLabel \
1613 and not egressLabel:
1614 cmd = "add-mpls-intent"
1615
1616 else:
1617 cmd = "add-mpls-intent"
1618
1619 if ethType:
1620 cmd += " --ethType " + str( ethType )
1621 if ethSrc:
1622 cmd += " --ethSrc " + str( ethSrc )
1623 if ethDst:
1624 cmd += " --ethDst " + str( ethDst )
1625 if bandwidth:
1626 cmd += " --bandwidth " + str( bandwidth )
1627 if lambdaAlloc:
1628 cmd += " --lambda "
1629 if ipProto:
1630 cmd += " --ipProto " + str( ipProto )
1631 if ipSrc:
1632 cmd += " --ipSrc " + str( ipSrc )
1633 if ipDst:
1634 cmd += " --ipDst " + str( ipDst )
1635 if tcpSrc:
1636 cmd += " --tcpSrc " + str( tcpSrc )
1637 if tcpDst:
1638 cmd += " --tcpDst " + str( tcpDst )
1639 if ingressLabel:
1640 cmd += " --ingressLabel " + str( ingressLabel )
1641 if egressLabel:
1642 cmd += " --egressLabel " + str( egressLabel )
1643 if priority:
1644 cmd += " --priority " + str( priority )
1645
1646 # Check whether the user appended the port
1647 # or provided it as an input
1648 if "/" in ingressDevice:
1649 cmd += " " + str( ingressDevice )
1650 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001651 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001652 main.log.error( "You must specify the ingress port" )
1653 return None
1654
1655 cmd += " " + \
1656 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001657 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001658
1659 if "/" in egressDevice:
1660 cmd += " " + str( egressDevice )
1661 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001662 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001663 main.log.error( "You must specify the egress port" )
1664 return None
1665
1666 cmd += " " +\
1667 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001668 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001669
1670 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001671 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001672 # If error, return error message
1673 if re.search( "Error", handle ):
1674 main.log.error( "Error in adding mpls intent" )
1675 return None
1676 else:
1677 # TODO: print out all the options in this message?
1678 main.log.info( "MPLS intent installed between " +
1679 str( ingressDevice ) + " and " +
1680 str( egressDevice ) )
1681 match = re.search('id=0x([\da-f]+),', handle)
1682 if match:
1683 return match.group()[3:-1]
1684 else:
1685 main.log.error( "Error, intent ID not found" )
1686 return None
Jon Hallc6793552016-01-19 14:18:37 -08001687 except AssertionError:
1688 main.log.exception( "" )
1689 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001690 except TypeError:
1691 main.log.exception( self.name + ": Object not as expected" )
1692 return None
1693 except pexpect.EOF:
1694 main.log.error( self.name + ": EOF exception found" )
1695 main.log.error( self.name + ": " + self.handle.before )
1696 main.cleanup()
1697 main.exit()
1698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
1700 main.cleanup()
1701 main.exit()
1702
Jon Hallefbd9792015-03-05 16:11:36 -08001703 def removeIntent( self, intentId, app='org.onosproject.cli',
1704 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001705 """
shahshreya1c818fc2015-02-26 13:44:08 -08001706 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001707 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001708 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001709 -p or --purge: Purge the intent from the store after removal
1710
Jon Halle3f39ff2015-01-13 11:50:53 -08001711 Returns:
1712 main.False on error and
1713 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001714 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001715 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001716 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001717 if purge:
1718 cmdStr += " -p"
1719 if sync:
1720 cmdStr += " -s"
1721
1722 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001724 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001725 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001726 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001727 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001728 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001729 # TODO: Should this be main.TRUE
1730 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001731 except AssertionError:
1732 main.log.exception( "" )
1733 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001734 except TypeError:
1735 main.log.exception( self.name + ": Object not as expected" )
1736 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001738 main.log.error( self.name + ": EOF exception found" )
1739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001740 main.cleanup()
1741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001744 main.cleanup()
1745 main.exit()
1746
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001747 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001748 """
1749 Purges all WITHDRAWN Intents
1750 """
1751 try:
1752 cmdStr = "purge-intents"
1753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001754 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001755 if re.search( "Error", handle ):
1756 main.log.error( "Error in purging intents" )
1757 return main.FALSE
1758 else:
1759 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001760 except AssertionError:
1761 main.log.exception( "" )
1762 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
1766 except pexpect.EOF:
1767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
1769 main.cleanup()
1770 main.exit()
1771 except Exception:
1772 main.log.exception( self.name + ": Uncaught exception!" )
1773 main.cleanup()
1774 main.exit()
1775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001777 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 NOTE: This method should be used after installing application:
1779 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001780 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001782 Description:
1783 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001784 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001785 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001786 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001788 cmdStr += " -j"
1789 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001790 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001791 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001792 except AssertionError:
1793 main.log.exception( "" )
1794 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001795 except TypeError:
1796 main.log.exception( self.name + ": Object not as expected" )
1797 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001798 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001799 main.log.error( self.name + ": EOF exception found" )
1800 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001801 main.cleanup()
1802 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001804 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001805 main.cleanup()
1806 main.exit()
1807
pingping-lin54b03372015-08-13 14:43:10 -07001808 def ipv4RouteNumber( self ):
1809 """
1810 NOTE: This method should be used after installing application:
1811 onos-app-sdnip
1812 Description:
1813 Obtain the total IPv4 routes number in the system
1814 """
1815 try:
1816 cmdStr = "routes -s -j"
1817 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001818 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001819 jsonResult = json.loads( handle )
1820 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001821 except AssertionError:
1822 main.log.exception( "" )
1823 return None
1824 except ( TypeError, ValueError ):
1825 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001826 return None
1827 except pexpect.EOF:
1828 main.log.error( self.name + ": EOF exception found" )
1829 main.log.error( self.name + ": " + self.handle.before )
1830 main.cleanup()
1831 main.exit()
1832 except Exception:
1833 main.log.exception( self.name + ": Uncaught exception!" )
1834 main.cleanup()
1835 main.exit()
1836
pingping-lin8244a3b2015-09-16 13:36:56 -07001837 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001838 """
andrewonlabe6745342014-10-17 14:29:13 -04001839 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001840 Obtain intents from the ONOS cli.
1841 Optional:
1842 * jsonFormat: Enable output formatting in json, default to True
1843 * summary: Whether only output the intent summary, defaults to False
1844 * type: Only output a certain type of intent. This options is valid
1845 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 """
andrewonlabe6745342014-10-17 14:29:13 -04001847 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001848 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001849 if summary:
1850 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001852 cmdStr += " -j"
1853 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001854 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001855 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001856 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001857 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001858 else:
Jon Hallff566d52016-01-15 14:45:36 -08001859 intentType = ""
1860 # IF we want the summary of a specific intent type
1861 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001862 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001863 if intentType in jsonResult.keys():
1864 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001865 else:
Jon Hallff566d52016-01-15 14:45:36 -08001866 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001867 return handle
1868 else:
1869 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001870 except AssertionError:
1871 main.log.exception( "" )
1872 return None
1873 except ( TypeError, ValueError ):
1874 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001875 return None
1876 except pexpect.EOF:
1877 main.log.error( self.name + ": EOF exception found" )
1878 main.log.error( self.name + ": " + self.handle.before )
1879 main.cleanup()
1880 main.exit()
1881 except Exception:
1882 main.log.exception( self.name + ": Uncaught exception!" )
1883 main.cleanup()
1884 main.exit()
1885
kelvin-onlab54400a92015-02-26 18:05:51 -08001886 def getIntentState(self, intentsId, intentsJson=None):
1887 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001888 Check intent state.
1889 Accepts a single intent ID (string type) or a list of intent IDs.
1890 Returns the state(string type) of the id if a single intent ID is
1891 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001892 Returns a dictionary with intent IDs as the key and its
1893 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001894 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001895 intentId: intent ID (string type)
1896 intentsJson: parsed json object from the onos:intents api
1897 Returns:
1898 state = An intent's state- INSTALL,WITHDRAWN etc.
1899 stateDict = Dictionary of intent's state. intent ID as the keys and
1900 state as the values.
1901 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001902 try:
1903 state = "State is Undefined"
1904 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001905 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001906 else:
Jon Hallc6793552016-01-19 14:18:37 -08001907 rawJson = intentsJson
1908 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001909 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001910 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001911 if intentsId == intent[ 'id' ]:
1912 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001913 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001914 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1915 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001916 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001917 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001918 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001919 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001920 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001921 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001922 if intentsId[ i ] == intents[ 'id' ]:
1923 stateDict[ 'state' ] = intents[ 'state' ]
1924 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001925 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001926 break
Jon Hallefbd9792015-03-05 16:11:36 -08001927 if len( intentsId ) != len( dictList ):
1928 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001929 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001930 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001931 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001932 return None
Jon Hallc6793552016-01-19 14:18:37 -08001933 except ( TypeError, ValueError ):
1934 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001935 return None
1936 except pexpect.EOF:
1937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
1939 main.cleanup()
1940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001941 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001942 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001943 main.cleanup()
1944 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001945
kelvin-onlabf512e942015-06-08 19:42:59 -07001946 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001947 """
1948 Description:
1949 Check intents state
1950 Required:
1951 intentsId - List of intents ID to be checked
1952 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001953 expectedState - Check the expected state(s) of each intents
1954 state in the list.
1955 *NOTE: You can pass in a list of expected state,
1956 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001957 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001958 Returns main.TRUE only if all intent are the same as expected states
1959 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001960 """
1961 try:
1962 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001963 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001964 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001965 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08001966 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001967 "getting intents state" )
1968 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001969
1970 if isinstance( expectedState, types.StringType ):
1971 for intents in intentsDict:
1972 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001973 main.log.debug( self.name + " : Intent ID - " +
1974 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001975 " actual state = " +
1976 intents.get( 'state' )
1977 + " does not equal expected state = "
1978 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001979 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001980
1981 elif isinstance( expectedState, types.ListType ):
1982 for intents in intentsDict:
1983 if not any( state == intents.get( 'state' ) for state in
1984 expectedState ):
1985 main.log.debug( self.name + " : Intent ID - " +
1986 intents.get( 'id' ) +
1987 " actual state = " +
1988 intents.get( 'state' ) +
1989 " does not equal expected states = "
1990 + str( expectedState ) )
1991 returnValue = main.FALSE
1992
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001993 if returnValue == main.TRUE:
1994 main.log.info( self.name + ": All " +
1995 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001996 " intents are in " + str( expectedState ) +
1997 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001998 return returnValue
1999 except TypeError:
2000 main.log.exception( self.name + ": Object not as expected" )
2001 return None
2002 except pexpect.EOF:
2003 main.log.error( self.name + ": EOF exception found" )
2004 main.log.error( self.name + ": " + self.handle.before )
2005 main.cleanup()
2006 main.exit()
2007 except Exception:
2008 main.log.exception( self.name + ": Uncaught exception!" )
2009 main.cleanup()
2010 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002011
GlennRCed771242016-01-13 17:02:47 -08002012 def checkIntentSummary( self, timeout=60 ):
2013 """
2014 Description:
2015 Check the number of installed intents.
2016 Optional:
2017 timeout - the timeout for pexcept
2018 Return:
2019 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2020 , otherwise, returns main.FALSE.
2021 """
2022
2023 try:
2024 cmd = "intents -s -j"
2025
2026 # Check response if something wrong
2027 response = self.sendline( cmd, timeout=timeout )
2028 if response == None:
2029 return main.False
2030 response = json.loads( response )
2031
2032 # get total and installed number, see if they are match
2033 allState = response.get( 'all' )
2034 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002035 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002036 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002037 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002038 return main.FALSE
2039
Jon Hallc6793552016-01-19 14:18:37 -08002040 except ( TypeError, ValueError ):
2041 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002042 return None
2043 except pexpect.EOF:
2044 main.log.error( self.name + ": EOF exception found" )
2045 main.log.error( self.name + ": " + self.handle.before )
2046 main.cleanup()
2047 main.exit()
2048 except Exception:
2049 main.log.exception( self.name + ": Uncaught exception!" )
2050 main.cleanup()
2051 main.exit()
2052
2053 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002054 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002055 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002057 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002058 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002059 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002060 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002061 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002062 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002063 cmdStr += " -j "
2064 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002065 handle = self.sendline( cmdStr, timeout=timeout )
2066 assert "Command not found:" not in handle, handle
2067 if re.search( "Error:", handle ):
2068 main.log.error( self.name + ": flows() response: " +
2069 str( handle ) )
2070 return handle
2071 except AssertionError:
2072 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002073 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002074 except TypeError:
2075 main.log.exception( self.name + ": Object not as expected" )
2076 return None
Jon Hallc6793552016-01-19 14:18:37 -08002077 except pexpect.TIMEOUT:
2078 main.log.error( self.name + ": ONOS timeout" )
2079 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002080 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002081 main.log.error( self.name + ": EOF exception found" )
2082 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002083 main.cleanup()
2084 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002085 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002086 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002087 main.cleanup()
2088 main.exit()
2089
GlennRCed771242016-01-13 17:02:47 -08002090
Jon Hallc6793552016-01-19 14:18:37 -08002091 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002092 """
2093 Description:
GlennRCed771242016-01-13 17:02:47 -08002094 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002095 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2096 if the count of those states is 0, which means all current flows
2097 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002098 Optional:
GlennRCed771242016-01-13 17:02:47 -08002099 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002100 Return:
2101 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002102 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002103 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002104 """
2105 try:
GlennRCed771242016-01-13 17:02:47 -08002106 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2107 checkedStates = []
2108 statesCount = [0, 0, 0, 0]
2109 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002110 rawFlows = self.flows( state=s, timeout = timeout )
2111 checkedStates.append( json.loads( rawFlows ) )
2112 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002113 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002114 try:
2115 statesCount[i] += int( c.get( "flowCount" ) )
2116 except TypeError:
2117 main.log.exception( "Json object not as expected" )
2118 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002119
GlennRCed771242016-01-13 17:02:47 -08002120 # We want to count PENDING_ADD if isPENDING is true
2121 if isPENDING:
2122 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2123 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002124 else:
GlennRCed771242016-01-13 17:02:47 -08002125 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2126 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002127 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002128 except ( TypeError, ValueError ):
2129 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002130 return None
2131 except pexpect.EOF:
2132 main.log.error( self.name + ": EOF exception found" )
2133 main.log.error( self.name + ": " + self.handle.before )
2134 main.cleanup()
2135 main.exit()
2136 except Exception:
2137 main.log.exception( self.name + ": Uncaught exception!" )
2138 main.cleanup()
2139 main.exit()
2140
GlennRCed771242016-01-13 17:02:47 -08002141 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2142 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002143 """
andrewonlab87852b02014-11-19 18:44:19 -05002144 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002145 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002146 a specific point-to-point intent definition
2147 Required:
GlennRCed771242016-01-13 17:02:47 -08002148 * ingress: specify source dpid
2149 * egress: specify destination dpid
2150 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002151 Optional:
GlennRCed771242016-01-13 17:02:47 -08002152 * offset: the keyOffset is where the next batch of intents
2153 will be installed
2154 Returns: If failed to push test intents, it will returen None,
2155 if successful, return true.
2156 Timeout expection will return None,
2157 TypeError will return false
2158 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002159 """
andrewonlab87852b02014-11-19 18:44:19 -05002160 try:
GlennRCed771242016-01-13 17:02:47 -08002161 if background:
2162 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002163 else:
GlennRCed771242016-01-13 17:02:47 -08002164 back = ""
2165 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002166 ingress,
2167 egress,
2168 batchSize,
2169 offset,
2170 back )
GlennRCed771242016-01-13 17:02:47 -08002171 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002172 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002173 main.log.info( response )
2174 if response == None:
2175 return None
2176
2177 # TODO: We should handle if there is failure in installation
2178 return main.TRUE
2179
Jon Hallc6793552016-01-19 14:18:37 -08002180 except AssertionError:
2181 main.log.exception( "" )
2182 return None
GlennRCed771242016-01-13 17:02:47 -08002183 except pexpect.TIMEOUT:
2184 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002185 return None
andrewonlab87852b02014-11-19 18:44:19 -05002186 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002189 main.cleanup()
2190 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002193 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002194 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002195 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002196 main.cleanup()
2197 main.exit()
2198
YPZhangf6f14a02016-01-28 15:17:31 -08002199 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002200 """
2201 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002202 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002203 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002204 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002205 """
2206 try:
YPZhangf6f14a02016-01-28 15:17:31 -08002207 cmd = "flows -s|grep ADDED|wc -l"
2208 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002209 if response == None:
2210 return -1
YPZhangf6f14a02016-01-28 15:17:31 -08002211 return int( response )
YPZhangb5d3f832016-01-23 22:54:26 -08002212 except TypeError:
2213 main.log.exception( self.name + ": Object not as expected" )
2214 return None
2215 except pexpect.EOF:
2216 main.log.error( self.name + ": EOF exception found" )
2217 main.log.error( self.name + ": " + self.handle.before )
2218 main.cleanup()
2219 main.exit()
2220 except Exception:
2221 main.log.exception( self.name + ": Uncaught exception!" )
2222 main.cleanup()
2223 main.exit()
2224
2225 def getTotalIntentsNum( self ):
2226 """
2227 Description:
2228 Get the total number of intents, include every states.
2229 Return:
2230 The number of intents
2231 """
2232 try:
2233 cmd = "summary -j"
2234 response = self.sendline( cmd )
2235 if response == None:
2236 return -1
2237 response = json.loads( response )
2238 return int( response.get("intents") )
2239 except TypeError:
2240 main.log.exception( self.name + ": Object not as expected" )
2241 return None
2242 except pexpect.EOF:
2243 main.log.error( self.name + ": EOF exception found" )
2244 main.log.error( self.name + ": " + self.handle.before )
2245 main.cleanup()
2246 main.exit()
2247 except Exception:
2248 main.log.exception( self.name + ": Uncaught exception!" )
2249 main.cleanup()
2250 main.exit()
2251
kelvin-onlabd3b64892015-01-20 13:26:24 -08002252 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002253 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002254 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002255 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002256 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002257 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002258 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002259 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002260 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002261 cmdStr += " -j"
2262 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002263 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002264 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002265 except AssertionError:
2266 main.log.exception( "" )
2267 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002268 except TypeError:
2269 main.log.exception( self.name + ": Object not as expected" )
2270 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002271 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002272 main.log.error( self.name + ": EOF exception found" )
2273 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002274 main.cleanup()
2275 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002276 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002277 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002278 main.cleanup()
2279 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002280
kelvin-onlabd3b64892015-01-20 13:26:24 -08002281 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002282 """
2283 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002284 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002286 """
andrewonlab867212a2014-10-22 20:13:38 -04002287 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002288 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002290 cmdStr += " -j"
2291 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002292 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002293 if handle:
2294 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002295 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002296 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002297 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002298 else:
2299 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002300 except AssertionError:
2301 main.log.exception( "" )
2302 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002303 except TypeError:
2304 main.log.exception( self.name + ": Object not as expected" )
2305 return None
andrewonlab867212a2014-10-22 20:13:38 -04002306 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002307 main.log.error( self.name + ": EOF exception found" )
2308 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002309 main.cleanup()
2310 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002311 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002312 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002313 main.cleanup()
2314 main.exit()
2315
kelvin8ec71442015-01-15 16:57:00 -08002316 # Wrapper functions ****************
2317 # Wrapper functions use existing driver
2318 # functions and extends their use case.
2319 # For example, we may use the output of
2320 # a normal driver function, and parse it
2321 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002322
kelvin-onlabd3b64892015-01-20 13:26:24 -08002323 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002324 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002325 Description:
2326 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002327 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002328 try:
kelvin8ec71442015-01-15 16:57:00 -08002329 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002330 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002331 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002332
kelvin8ec71442015-01-15 16:57:00 -08002333 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002334 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2335 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002336 match = re.search('id=0x([\da-f]+),', intents)
2337 if match:
2338 tmpId = match.group()[3:-1]
2339 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002340 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002341
Jon Halld4d4b372015-01-28 16:02:41 -08002342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002348 main.cleanup()
2349 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002350 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002351 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002352 main.cleanup()
2353 main.exit()
2354
Jon Hall30b82fa2015-03-04 17:15:43 -08002355 def FlowAddedCount( self, deviceId ):
2356 """
2357 Determine the number of flow rules for the given device id that are
2358 in the added state
2359 """
2360 try:
2361 cmdStr = "flows any " + str( deviceId ) + " | " +\
2362 "grep 'state=ADDED' | wc -l"
2363 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002364 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002365 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002366 except AssertionError:
2367 main.log.exception( "" )
2368 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002369 except pexpect.EOF:
2370 main.log.error( self.name + ": EOF exception found" )
2371 main.log.error( self.name + ": " + self.handle.before )
2372 main.cleanup()
2373 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002374 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002375 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002376 main.cleanup()
2377 main.exit()
2378
kelvin-onlabd3b64892015-01-20 13:26:24 -08002379 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002380 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002381 Use 'devices' function to obtain list of all devices
2382 and parse the result to obtain a list of all device
2383 id's. Returns this list. Returns empty list if no
2384 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002385 List is ordered sequentially
2386
andrewonlab3e15ead2014-10-15 14:21:34 -04002387 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002388 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002389 the ids. By obtaining the list of device ids on the fly,
2390 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002391 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002392 try:
kelvin8ec71442015-01-15 16:57:00 -08002393 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002394 devicesStr = self.devices( jsonFormat=False )
2395 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002396
kelvin-onlabd3b64892015-01-20 13:26:24 -08002397 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002398 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002399 return idList
kelvin8ec71442015-01-15 16:57:00 -08002400
2401 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002402 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002403 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002404 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002405 # Split list further into arguments before and after string
2406 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002407 # append to idList
2408 for arg in tempList:
2409 idList.append( arg.split( "id=" )[ 1 ] )
2410 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002411
Jon Halld4d4b372015-01-28 16:02:41 -08002412 except TypeError:
2413 main.log.exception( self.name + ": Object not as expected" )
2414 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002415 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002416 main.log.error( self.name + ": EOF exception found" )
2417 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002418 main.cleanup()
2419 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002420 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002421 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002422 main.cleanup()
2423 main.exit()
2424
kelvin-onlabd3b64892015-01-20 13:26:24 -08002425 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002426 """
andrewonlab7c211572014-10-15 16:45:20 -04002427 Uses 'nodes' function to obtain list of all nodes
2428 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002429 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002430 Returns:
2431 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002432 """
andrewonlab7c211572014-10-15 16:45:20 -04002433 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002434 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002435 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002436 # Sample nodesStr output
2437 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002438 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002439 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002440 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002441 nodesJson = json.loads( nodesStr )
2442 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002443 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002444 except ( TypeError, ValueError ):
2445 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002446 return None
andrewonlab7c211572014-10-15 16:45:20 -04002447 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002448 main.log.error( self.name + ": EOF exception found" )
2449 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002450 main.cleanup()
2451 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002452 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002453 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002454 main.cleanup()
2455 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002456
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002458 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002459 Return the first device from the devices api whose 'id' contains 'dpid'
2460 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002461 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002462 try:
kelvin8ec71442015-01-15 16:57:00 -08002463 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002464 return None
2465 else:
kelvin8ec71442015-01-15 16:57:00 -08002466 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002467 rawDevices = self.devices()
2468 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002469 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002470 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002471 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2472 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002473 return device
2474 return None
Jon Hallc6793552016-01-19 14:18:37 -08002475 except ( TypeError, ValueError ):
2476 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002477 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002478 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002479 main.log.error( self.name + ": EOF exception found" )
2480 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002481 main.cleanup()
2482 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002483 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002484 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002485 main.cleanup()
2486 main.exit()
2487
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002489 """
Jon Hallefbd9792015-03-05 16:11:36 -08002490 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002491 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002492 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002493
Jon Hall42db6dc2014-10-24 19:03:48 -04002494 Params: ip = ip used for the onos cli
2495 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002496 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002497 logLevel = level to log to. Currently accepts
2498 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002499
2500
kelvin-onlabd3b64892015-01-20 13:26:24 -08002501 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002502
Jon Hallefbd9792015-03-05 16:11:36 -08002503 Returns: main.TRUE if the number of switches and links are correct,
2504 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002505 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002506 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002507 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002509 if topology == {}:
2510 return main.ERROR
2511 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002512 # Is the number of switches is what we expected
2513 devices = topology.get( 'devices', False )
2514 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002515 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002516 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002517 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002518 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002519 linkCheck = ( int( links ) == int( numolink ) )
2520 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002521 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002522 output += "The number of links and switches match " +\
2523 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002524 result = main.TRUE
2525 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002526 output += "The number of links and switches does not match " +\
2527 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002528 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002529 output = output + "\n ONOS sees %i devices (%i expected) \
2530 and %i links (%i expected)" % (
2531 int( devices ), int( numoswitch ), int( links ),
2532 int( numolink ) )
2533 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002534 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002535 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002536 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002537 else:
Jon Hall390696c2015-05-05 17:13:41 -07002538 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002539 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002540 except TypeError:
2541 main.log.exception( self.name + ": Object not as expected" )
2542 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002543 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002544 main.log.error( self.name + ": EOF exception found" )
2545 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002546 main.cleanup()
2547 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002548 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002549 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002550 main.cleanup()
2551 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002552
kelvin-onlabd3b64892015-01-20 13:26:24 -08002553 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002554 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002555 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002556 deviceId must be the id of a device as seen in the onos devices command
2557 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002558 role must be either master, standby, or none
2559
Jon Halle3f39ff2015-01-13 11:50:53 -08002560 Returns:
2561 main.TRUE or main.FALSE based on argument verification and
2562 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002563 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002564 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002565 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002566 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 cmdStr = "device-role " +\
2568 str( deviceId ) + " " +\
2569 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002570 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002571 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002572 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002573 if re.search( "Error", handle ):
2574 # end color output to escape any colours
2575 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002576 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002577 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002578 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002579 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002580 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002581 main.log.error( "Invalid 'role' given to device_role(). " +
2582 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002583 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002584 except AssertionError:
2585 main.log.exception( "" )
2586 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002587 except TypeError:
2588 main.log.exception( self.name + ": Object not as expected" )
2589 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002590 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002591 main.log.error( self.name + ": EOF exception found" )
2592 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002593 main.cleanup()
2594 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002595 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002596 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002597 main.cleanup()
2598 main.exit()
2599
kelvin-onlabd3b64892015-01-20 13:26:24 -08002600 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002601 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002602 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002603 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002604 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002605 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002606 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002607 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002609 cmdStr += " -j"
2610 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002611 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002612 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002613 except AssertionError:
2614 main.log.exception( "" )
2615 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002616 except TypeError:
2617 main.log.exception( self.name + ": Object not as expected" )
2618 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002619 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002620 main.log.error( self.name + ": EOF exception found" )
2621 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002622 main.cleanup()
2623 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002624 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002625 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002626 main.cleanup()
2627 main.exit()
2628
kelvin-onlabd3b64892015-01-20 13:26:24 -08002629 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002630 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002631 CLI command to get the current leader for the Election test application
2632 NOTE: Requires installation of the onos-app-election feature
2633 Returns: Node IP of the leader if one exists
2634 None if none exists
2635 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002636 """
Jon Hall94fd0472014-12-08 11:52:42 -08002637 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002638 cmdStr = "election-test-leader"
2639 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002640 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002641 # Leader
2642 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002643 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 nodeSearch = re.search( leaderPattern, response )
2645 if nodeSearch:
2646 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002647 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002648 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002649 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002650 # no leader
2651 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002652 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 nullSearch = re.search( nullPattern, response )
2654 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002655 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002656 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002657 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002658 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002659 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002660 if re.search( errorPattern, response ):
2661 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002662 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002663 return main.FALSE
2664 else:
Jon Hall390696c2015-05-05 17:13:41 -07002665 main.log.error( "Error in electionTestLeader on " + self.name +
2666 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002667 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002668 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002669 except AssertionError:
2670 main.log.exception( "" )
2671 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002672 except TypeError:
2673 main.log.exception( self.name + ": Object not as expected" )
2674 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002675 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002676 main.log.error( self.name + ": EOF exception found" )
2677 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002678 main.cleanup()
2679 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002680 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002681 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002682 main.cleanup()
2683 main.exit()
2684
kelvin-onlabd3b64892015-01-20 13:26:24 -08002685 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002686 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002687 CLI command to run for leadership of the Election test application.
2688 NOTE: Requires installation of the onos-app-election feature
2689 Returns: Main.TRUE on success
2690 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002691 """
Jon Hall94fd0472014-12-08 11:52:42 -08002692 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 cmdStr = "election-test-run"
2694 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002695 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002696 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002697 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002698 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002699 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002700 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002701 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002702 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002703 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002704 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002705 errorPattern = "Command\snot\sfound"
2706 if re.search( errorPattern, response ):
2707 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002708 return main.FALSE
2709 else:
Jon Hall390696c2015-05-05 17:13:41 -07002710 main.log.error( "Error in electionTestRun on " + self.name +
2711 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002712 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002713 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002714 except AssertionError:
2715 main.log.exception( "" )
2716 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002717 except TypeError:
2718 main.log.exception( self.name + ": Object not as expected" )
2719 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002720 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002721 main.log.error( self.name + ": EOF exception found" )
2722 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002723 main.cleanup()
2724 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002725 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002726 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002727 main.cleanup()
2728 main.exit()
2729
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002731 """
Jon Hall94fd0472014-12-08 11:52:42 -08002732 * CLI command to withdraw the local node from leadership election for
2733 * the Election test application.
2734 #NOTE: Requires installation of the onos-app-election feature
2735 Returns: Main.TRUE on success
2736 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002737 """
Jon Hall94fd0472014-12-08 11:52:42 -08002738 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002739 cmdStr = "election-test-withdraw"
2740 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002741 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002742 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002743 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002744 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002745 if re.search( successPattern, response ):
2746 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002747 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002748 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002749 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002750 errorPattern = "Command\snot\sfound"
2751 if re.search( errorPattern, response ):
2752 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002753 return main.FALSE
2754 else:
Jon Hall390696c2015-05-05 17:13:41 -07002755 main.log.error( "Error in electionTestWithdraw on " +
2756 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002757 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002758 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002759 except AssertionError:
2760 main.log.exception( "" )
2761 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002762 except TypeError:
2763 main.log.exception( self.name + ": Object not as expected" )
2764 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002768 main.cleanup()
2769 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002772 main.cleanup()
2773 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002774
kelvin8ec71442015-01-15 16:57:00 -08002775 def getDevicePortsEnabledCount( self, dpid ):
2776 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002777 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002778 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002779 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002780 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2782 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002783 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002784 if re.search( "No such device", output ):
2785 main.log.error( "Error in getting ports" )
2786 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002787 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002788 return output
Jon Hallc6793552016-01-19 14:18:37 -08002789 except AssertionError:
2790 main.log.exception( "" )
2791 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002792 except TypeError:
2793 main.log.exception( self.name + ": Object not as expected" )
2794 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002795 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002796 main.log.error( self.name + ": EOF exception found" )
2797 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002798 main.cleanup()
2799 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002800 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002801 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002802 main.cleanup()
2803 main.exit()
2804
kelvin8ec71442015-01-15 16:57:00 -08002805 def getDeviceLinksActiveCount( self, dpid ):
2806 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002807 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002809 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002810 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2812 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002813 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002814 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002815 main.log.error( "Error in getting ports " )
2816 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002817 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002818 return output
Jon Hallc6793552016-01-19 14:18:37 -08002819 except AssertionError:
2820 main.log.exception( "" )
2821 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002822 except TypeError:
2823 main.log.exception( self.name + ": Object not as expected" )
2824 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002825 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002826 main.log.error( self.name + ": EOF exception found" )
2827 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002828 main.cleanup()
2829 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002830 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002831 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002832 main.cleanup()
2833 main.exit()
2834
kelvin8ec71442015-01-15 16:57:00 -08002835 def getAllIntentIds( self ):
2836 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002837 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002838 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002839 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002840 cmdStr = "onos:intents | grep id="
2841 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002842 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002843 if re.search( "Error", output ):
2844 main.log.error( "Error in getting ports" )
2845 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002846 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002847 return output
Jon Hallc6793552016-01-19 14:18:37 -08002848 except AssertionError:
2849 main.log.exception( "" )
2850 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002851 except TypeError:
2852 main.log.exception( self.name + ": Object not as expected" )
2853 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002854 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002855 main.log.error( self.name + ": EOF exception found" )
2856 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002857 main.cleanup()
2858 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002859 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002860 main.log.exception( self.name + ": Uncaught exception!" )
2861 main.cleanup()
2862 main.exit()
2863
Jon Hall73509952015-02-24 16:42:56 -08002864 def intentSummary( self ):
2865 """
Jon Hallefbd9792015-03-05 16:11:36 -08002866 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002867 """
2868 try:
2869 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002870 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002871 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002872 states.append( intent.get( 'state', None ) )
2873 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002874 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002875 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002876 except ( TypeError, ValueError ):
2877 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002878 return None
2879 except pexpect.EOF:
2880 main.log.error( self.name + ": EOF exception found" )
2881 main.log.error( self.name + ": " + self.handle.before )
2882 main.cleanup()
2883 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002884 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002885 main.log.exception( self.name + ": Uncaught exception!" )
2886 main.cleanup()
2887 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002888
Jon Hall61282e32015-03-19 11:34:11 -07002889 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002890 """
2891 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002892 Optional argument:
2893 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002894 """
Jon Hall63604932015-02-26 17:09:50 -08002895 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002896 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002897 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002898 cmdStr += " -j"
2899 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002900 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002901 return output
Jon Hallc6793552016-01-19 14:18:37 -08002902 except AssertionError:
2903 main.log.exception( "" )
2904 return None
Jon Hall63604932015-02-26 17:09:50 -08002905 except TypeError:
2906 main.log.exception( self.name + ": Object not as expected" )
2907 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002908 except pexpect.EOF:
2909 main.log.error( self.name + ": EOF exception found" )
2910 main.log.error( self.name + ": " + self.handle.before )
2911 main.cleanup()
2912 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002913 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002914 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002915 main.cleanup()
2916 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002917
acsmarsa4a4d1e2015-07-10 16:01:24 -07002918 def leaderCandidates( self, jsonFormat=True ):
2919 """
2920 Returns the output of the leaders -c command.
2921 Optional argument:
2922 * jsonFormat - boolean indicating if you want output in json
2923 """
2924 try:
2925 cmdStr = "onos:leaders -c"
2926 if jsonFormat:
2927 cmdStr += " -j"
2928 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002929 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002930 return output
Jon Hallc6793552016-01-19 14:18:37 -08002931 except AssertionError:
2932 main.log.exception( "" )
2933 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002934 except TypeError:
2935 main.log.exception( self.name + ": Object not as expected" )
2936 return None
2937 except pexpect.EOF:
2938 main.log.error( self.name + ": EOF exception found" )
2939 main.log.error( self.name + ": " + self.handle.before )
2940 main.cleanup()
2941 main.exit()
2942 except Exception:
2943 main.log.exception( self.name + ": Uncaught exception!" )
2944 main.cleanup()
2945 main.exit()
2946
Jon Hallc6793552016-01-19 14:18:37 -08002947 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002948 """
2949 Returns a list in format [leader,candidate1,candidate2,...] for a given
2950 topic parameter and an empty list if the topic doesn't exist
2951 If no leader is elected leader in the returned list will be "none"
2952 Returns None if there is a type error processing the json object
2953 """
2954 try:
Jon Hall6e709752016-02-01 13:38:46 -08002955 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08002956 rawOutput = self.sendline( cmdStr )
2957 assert "Command not found:" not in rawOutput, rawOutput
2958 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002959 results = []
2960 for dict in output:
2961 if dict["topic"] == topic:
2962 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002963 candidates = re.split( ", ", dict["candidates"][1:-1] )
2964 results.append( leader )
2965 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002966 return results
Jon Hallc6793552016-01-19 14:18:37 -08002967 except AssertionError:
2968 main.log.exception( "" )
2969 return None
2970 except ( TypeError, ValueError ):
2971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002972 return None
2973 except pexpect.EOF:
2974 main.log.error( self.name + ": EOF exception found" )
2975 main.log.error( self.name + ": " + self.handle.before )
2976 main.cleanup()
2977 main.exit()
2978 except Exception:
2979 main.log.exception( self.name + ": Uncaught exception!" )
2980 main.cleanup()
2981 main.exit()
2982
Jon Hall61282e32015-03-19 11:34:11 -07002983 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002984 """
2985 Returns the output of the intent Pending map.
2986 """
Jon Hall63604932015-02-26 17:09:50 -08002987 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002988 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002989 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002990 cmdStr += " -j"
2991 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002992 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002993 return output
Jon Hallc6793552016-01-19 14:18:37 -08002994 except AssertionError:
2995 main.log.exception( "" )
2996 return None
Jon Hall63604932015-02-26 17:09:50 -08002997 except TypeError:
2998 main.log.exception( self.name + ": Object not as expected" )
2999 return None
3000 except pexpect.EOF:
3001 main.log.error( self.name + ": EOF exception found" )
3002 main.log.error( self.name + ": " + self.handle.before )
3003 main.cleanup()
3004 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003005 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003006 main.log.exception( self.name + ": Uncaught exception!" )
3007 main.cleanup()
3008 main.exit()
3009
Jon Hall61282e32015-03-19 11:34:11 -07003010 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003011 """
3012 Returns the output of the raft partitions command for ONOS.
3013 """
Jon Hall61282e32015-03-19 11:34:11 -07003014 # Sample JSON
3015 # {
3016 # "leader": "tcp://10.128.30.11:7238",
3017 # "members": [
3018 # "tcp://10.128.30.11:7238",
3019 # "tcp://10.128.30.17:7238",
3020 # "tcp://10.128.30.13:7238",
3021 # ],
3022 # "name": "p1",
3023 # "term": 3
3024 # },
Jon Hall63604932015-02-26 17:09:50 -08003025 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003026 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003027 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003028 cmdStr += " -j"
3029 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003030 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003031 return output
Jon Hallc6793552016-01-19 14:18:37 -08003032 except AssertionError:
3033 main.log.exception( "" )
3034 return None
Jon Hall63604932015-02-26 17:09:50 -08003035 except TypeError:
3036 main.log.exception( self.name + ": Object not as expected" )
3037 return None
3038 except pexpect.EOF:
3039 main.log.error( self.name + ": EOF exception found" )
3040 main.log.error( self.name + ": " + self.handle.before )
3041 main.cleanup()
3042 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003043 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003044 main.log.exception( self.name + ": Uncaught exception!" )
3045 main.cleanup()
3046 main.exit()
3047
Jon Hallbe379602015-03-24 13:39:32 -07003048 def apps( self, jsonFormat=True ):
3049 """
3050 Returns the output of the apps command for ONOS. This command lists
3051 information about installed ONOS applications
3052 """
3053 # Sample JSON object
3054 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3055 # "description":"ONOS OpenFlow protocol southbound providers",
3056 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3057 # "features":"[onos-openflow]","state":"ACTIVE"}]
3058 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003059 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003060 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003061 cmdStr += " -j"
3062 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003063 assert "Command not found:" not in output, output
3064 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003065 return output
Jon Hallbe379602015-03-24 13:39:32 -07003066 # FIXME: look at specific exceptions/Errors
3067 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003068 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003069 return None
3070 except TypeError:
3071 main.log.exception( self.name + ": Object not as expected" )
3072 return None
3073 except pexpect.EOF:
3074 main.log.error( self.name + ": EOF exception found" )
3075 main.log.error( self.name + ": " + self.handle.before )
3076 main.cleanup()
3077 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003078 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003079 main.log.exception( self.name + ": Uncaught exception!" )
3080 main.cleanup()
3081 main.exit()
3082
Jon Hall146f1522015-03-24 15:33:24 -07003083 def appStatus( self, appName ):
3084 """
3085 Uses the onos:apps cli command to return the status of an application.
3086 Returns:
3087 "ACTIVE" - If app is installed and activated
3088 "INSTALLED" - If app is installed and deactivated
3089 "UNINSTALLED" - If app is not installed
3090 None - on error
3091 """
Jon Hall146f1522015-03-24 15:33:24 -07003092 try:
3093 if not isinstance( appName, types.StringType ):
3094 main.log.error( self.name + ".appStatus(): appName must be" +
3095 " a string" )
3096 return None
3097 output = self.apps( jsonFormat=True )
3098 appsJson = json.loads( output )
3099 state = None
3100 for app in appsJson:
3101 if appName == app.get('name'):
3102 state = app.get('state')
3103 break
3104 if state == "ACTIVE" or state == "INSTALLED":
3105 return state
3106 elif state is None:
3107 return "UNINSTALLED"
3108 elif state:
3109 main.log.error( "Unexpected state from 'onos:apps': " +
3110 str( state ) )
3111 return state
Jon Hallc6793552016-01-19 14:18:37 -08003112 except ( TypeError, ValueError ):
3113 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3114 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003115 return None
3116 except pexpect.EOF:
3117 main.log.error( self.name + ": EOF exception found" )
3118 main.log.error( self.name + ": " + self.handle.before )
3119 main.cleanup()
3120 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003121 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003122 main.log.exception( self.name + ": Uncaught exception!" )
3123 main.cleanup()
3124 main.exit()
3125
Jon Hallbe379602015-03-24 13:39:32 -07003126 def app( self, appName, option ):
3127 """
3128 Interacts with the app command for ONOS. This command manages
3129 application inventory.
3130 """
Jon Hallbe379602015-03-24 13:39:32 -07003131 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003132 # Validate argument types
3133 valid = True
3134 if not isinstance( appName, types.StringType ):
3135 main.log.error( self.name + ".app(): appName must be a " +
3136 "string" )
3137 valid = False
3138 if not isinstance( option, types.StringType ):
3139 main.log.error( self.name + ".app(): option must be a string" )
3140 valid = False
3141 if not valid:
3142 return main.FALSE
3143 # Validate Option
3144 option = option.lower()
3145 # NOTE: Install may become a valid option
3146 if option == "activate":
3147 pass
3148 elif option == "deactivate":
3149 pass
3150 elif option == "uninstall":
3151 pass
3152 else:
3153 # Invalid option
3154 main.log.error( "The ONOS app command argument only takes " +
3155 "the values: (activate|deactivate|uninstall)" +
3156 "; was given '" + option + "'")
3157 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003158 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003159 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003160 if "Error executing command" in output:
3161 main.log.error( "Error in processing onos:app command: " +
3162 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003163 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003164 elif "No such application" in output:
3165 main.log.error( "The application '" + appName +
3166 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003167 return main.FALSE
3168 elif "Command not found:" in output:
3169 main.log.error( "Error in processing onos:app command: " +
3170 str( output ) )
3171 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003172 elif "Unsupported command:" in output:
3173 main.log.error( "Incorrect command given to 'app': " +
3174 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003175 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003176 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003177 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003178 return main.TRUE
3179 except TypeError:
3180 main.log.exception( self.name + ": Object not as expected" )
3181 return main.ERROR
3182 except pexpect.EOF:
3183 main.log.error( self.name + ": EOF exception found" )
3184 main.log.error( self.name + ": " + self.handle.before )
3185 main.cleanup()
3186 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003187 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003188 main.log.exception( self.name + ": Uncaught exception!" )
3189 main.cleanup()
3190 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003191
Jon Hallbd16b922015-03-26 17:53:15 -07003192 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003193 """
3194 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003195 appName is the hierarchical app name, not the feature name
3196 If check is True, method will check the status of the app after the
3197 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003198 Returns main.TRUE if the command was successfully sent
3199 main.FALSE if the cli responded with an error or given
3200 incorrect input
3201 """
3202 try:
3203 if not isinstance( appName, types.StringType ):
3204 main.log.error( self.name + ".activateApp(): appName must be" +
3205 " a string" )
3206 return main.FALSE
3207 status = self.appStatus( appName )
3208 if status == "INSTALLED":
3209 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003210 if check and response == main.TRUE:
3211 for i in range(10): # try 10 times then give up
3212 # TODO: Check with Thomas about this delay
3213 status = self.appStatus( appName )
3214 if status == "ACTIVE":
3215 return main.TRUE
3216 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003217 main.log.debug( "The state of application " +
3218 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003219 time.sleep( 1 )
3220 return main.FALSE
3221 else: # not 'check' or command didn't succeed
3222 return response
Jon Hall146f1522015-03-24 15:33:24 -07003223 elif status == "ACTIVE":
3224 return main.TRUE
3225 elif status == "UNINSTALLED":
3226 main.log.error( self.name + ": Tried to activate the " +
3227 "application '" + appName + "' which is not " +
3228 "installed." )
3229 else:
3230 main.log.error( "Unexpected return value from appStatus: " +
3231 str( status ) )
3232 return main.ERROR
3233 except TypeError:
3234 main.log.exception( self.name + ": Object not as expected" )
3235 return main.ERROR
3236 except pexpect.EOF:
3237 main.log.error( self.name + ": EOF exception found" )
3238 main.log.error( self.name + ": " + self.handle.before )
3239 main.cleanup()
3240 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003241 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003242 main.log.exception( self.name + ": Uncaught exception!" )
3243 main.cleanup()
3244 main.exit()
3245
Jon Hallbd16b922015-03-26 17:53:15 -07003246 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003247 """
3248 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003249 appName is the hierarchical app name, not the feature name
3250 If check is True, method will check the status of the app after the
3251 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003252 Returns main.TRUE if the command was successfully sent
3253 main.FALSE if the cli responded with an error or given
3254 incorrect input
3255 """
3256 try:
3257 if not isinstance( appName, types.StringType ):
3258 main.log.error( self.name + ".deactivateApp(): appName must " +
3259 "be a string" )
3260 return main.FALSE
3261 status = self.appStatus( appName )
3262 if status == "INSTALLED":
3263 return main.TRUE
3264 elif status == "ACTIVE":
3265 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003266 if check and response == main.TRUE:
3267 for i in range(10): # try 10 times then give up
3268 status = self.appStatus( appName )
3269 if status == "INSTALLED":
3270 return main.TRUE
3271 else:
3272 time.sleep( 1 )
3273 return main.FALSE
3274 else: # not check or command didn't succeed
3275 return response
Jon Hall146f1522015-03-24 15:33:24 -07003276 elif status == "UNINSTALLED":
3277 main.log.warn( self.name + ": Tried to deactivate the " +
3278 "application '" + appName + "' which is not " +
3279 "installed." )
3280 return main.TRUE
3281 else:
3282 main.log.error( "Unexpected return value from appStatus: " +
3283 str( status ) )
3284 return main.ERROR
3285 except TypeError:
3286 main.log.exception( self.name + ": Object not as expected" )
3287 return main.ERROR
3288 except pexpect.EOF:
3289 main.log.error( self.name + ": EOF exception found" )
3290 main.log.error( self.name + ": " + self.handle.before )
3291 main.cleanup()
3292 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003293 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003294 main.log.exception( self.name + ": Uncaught exception!" )
3295 main.cleanup()
3296 main.exit()
3297
Jon Hallbd16b922015-03-26 17:53:15 -07003298 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003299 """
3300 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003301 appName is the hierarchical app name, not the feature name
3302 If check is True, method will check the status of the app after the
3303 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003304 Returns main.TRUE if the command was successfully sent
3305 main.FALSE if the cli responded with an error or given
3306 incorrect input
3307 """
3308 # TODO: check with Thomas about the state machine for apps
3309 try:
3310 if not isinstance( appName, types.StringType ):
3311 main.log.error( self.name + ".uninstallApp(): appName must " +
3312 "be a string" )
3313 return main.FALSE
3314 status = self.appStatus( appName )
3315 if status == "INSTALLED":
3316 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003317 if check and response == main.TRUE:
3318 for i in range(10): # try 10 times then give up
3319 status = self.appStatus( appName )
3320 if status == "UNINSTALLED":
3321 return main.TRUE
3322 else:
3323 time.sleep( 1 )
3324 return main.FALSE
3325 else: # not check or command didn't succeed
3326 return response
Jon Hall146f1522015-03-24 15:33:24 -07003327 elif status == "ACTIVE":
3328 main.log.warn( self.name + ": Tried to uninstall the " +
3329 "application '" + appName + "' which is " +
3330 "currently active." )
3331 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003332 if check and response == main.TRUE:
3333 for i in range(10): # try 10 times then give up
3334 status = self.appStatus( appName )
3335 if status == "UNINSTALLED":
3336 return main.TRUE
3337 else:
3338 time.sleep( 1 )
3339 return main.FALSE
3340 else: # not check or command didn't succeed
3341 return response
Jon Hall146f1522015-03-24 15:33:24 -07003342 elif status == "UNINSTALLED":
3343 return main.TRUE
3344 else:
3345 main.log.error( "Unexpected return value from appStatus: " +
3346 str( status ) )
3347 return main.ERROR
3348 except TypeError:
3349 main.log.exception( self.name + ": Object not as expected" )
3350 return main.ERROR
3351 except pexpect.EOF:
3352 main.log.error( self.name + ": EOF exception found" )
3353 main.log.error( self.name + ": " + self.handle.before )
3354 main.cleanup()
3355 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003356 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003357 main.log.exception( self.name + ": Uncaught exception!" )
3358 main.cleanup()
3359 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003360
3361 def appIDs( self, jsonFormat=True ):
3362 """
3363 Show the mappings between app id and app names given by the 'app-ids'
3364 cli command
3365 """
3366 try:
3367 cmdStr = "app-ids"
3368 if jsonFormat:
3369 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003370 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003371 assert "Command not found:" not in output, output
3372 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003374 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003375 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003376 return None
3377 except TypeError:
3378 main.log.exception( self.name + ": Object not as expected" )
3379 return None
3380 except pexpect.EOF:
3381 main.log.error( self.name + ": EOF exception found" )
3382 main.log.error( self.name + ": " + self.handle.before )
3383 main.cleanup()
3384 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003385 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003386 main.log.exception( self.name + ": Uncaught exception!" )
3387 main.cleanup()
3388 main.exit()
3389
3390 def appToIDCheck( self ):
3391 """
3392 This method will check that each application's ID listed in 'apps' is
3393 the same as the ID listed in 'app-ids'. The check will also check that
3394 there are no duplicate IDs issued. Note that an app ID should be
3395 a globaly unique numerical identifier for app/app-like features. Once
3396 an ID is registered, the ID is never freed up so that if an app is
3397 reinstalled it will have the same ID.
3398
3399 Returns: main.TRUE if the check passes and
3400 main.FALSE if the check fails or
3401 main.ERROR if there is some error in processing the test
3402 """
3403 try:
Jon Hall390696c2015-05-05 17:13:41 -07003404 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003405 rawJson = self.appIDs( jsonFormat=True )
3406 if rawJson:
3407 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003408 else:
Jon Hallc6793552016-01-19 14:18:37 -08003409 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003410 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003411 rawJson = self.apps( jsonFormat=True )
3412 if rawJson:
3413 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003414 else:
Jon Hallc6793552016-01-19 14:18:37 -08003415 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003416 bail = True
3417 if bail:
3418 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003419 result = main.TRUE
3420 for app in apps:
3421 appID = app.get( 'id' )
3422 if appID is None:
3423 main.log.error( "Error parsing app: " + str( app ) )
3424 result = main.FALSE
3425 appName = app.get( 'name' )
3426 if appName is None:
3427 main.log.error( "Error parsing app: " + str( app ) )
3428 result = main.FALSE
3429 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003430 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003431 # main.log.debug( "Comparing " + str( app ) + " to " +
3432 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003433 if not current: # if ids doesn't have this id
3434 result = main.FALSE
3435 main.log.error( "'app-ids' does not have the ID for " +
3436 str( appName ) + " that apps does." )
3437 elif len( current ) > 1:
3438 # there is more than one app with this ID
3439 result = main.FALSE
3440 # We will log this later in the method
3441 elif not current[0][ 'name' ] == appName:
3442 currentName = current[0][ 'name' ]
3443 result = main.FALSE
3444 main.log.error( "'app-ids' has " + str( currentName ) +
3445 " registered under id:" + str( appID ) +
3446 " but 'apps' has " + str( appName ) )
3447 else:
3448 pass # id and name match!
3449 # now make sure that app-ids has no duplicates
3450 idsList = []
3451 namesList = []
3452 for item in ids:
3453 idsList.append( item[ 'id' ] )
3454 namesList.append( item[ 'name' ] )
3455 if len( idsList ) != len( set( idsList ) ) or\
3456 len( namesList ) != len( set( namesList ) ):
3457 main.log.error( "'app-ids' has some duplicate entries: \n"
3458 + json.dumps( ids,
3459 sort_keys=True,
3460 indent=4,
3461 separators=( ',', ': ' ) ) )
3462 result = main.FALSE
3463 return result
Jon Hallc6793552016-01-19 14:18:37 -08003464 except ( TypeError, ValueError ):
3465 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003466 return main.ERROR
3467 except pexpect.EOF:
3468 main.log.error( self.name + ": EOF exception found" )
3469 main.log.error( self.name + ": " + self.handle.before )
3470 main.cleanup()
3471 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003472 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003473 main.log.exception( self.name + ": Uncaught exception!" )
3474 main.cleanup()
3475 main.exit()
3476
Jon Hallfb760a02015-04-13 15:35:03 -07003477 def getCfg( self, component=None, propName=None, short=False,
3478 jsonFormat=True ):
3479 """
3480 Get configuration settings from onos cli
3481 Optional arguments:
3482 component - Optionally only list configurations for a specific
3483 component. If None, all components with configurations
3484 are displayed. Case Sensitive string.
3485 propName - If component is specified, propName option will show
3486 only this specific configuration from that component.
3487 Case Sensitive string.
3488 jsonFormat - Returns output as json. Note that this will override
3489 the short option
3490 short - Short, less verbose, version of configurations.
3491 This is overridden by the json option
3492 returns:
3493 Output from cli as a string or None on error
3494 """
3495 try:
3496 baseStr = "cfg"
3497 cmdStr = " get"
3498 componentStr = ""
3499 if component:
3500 componentStr += " " + component
3501 if propName:
3502 componentStr += " " + propName
3503 if jsonFormat:
3504 baseStr += " -j"
3505 elif short:
3506 baseStr += " -s"
3507 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003508 assert "Command not found:" not in output, output
3509 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003510 return output
3511 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003512 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003513 return None
3514 except TypeError:
3515 main.log.exception( self.name + ": Object not as expected" )
3516 return None
3517 except pexpect.EOF:
3518 main.log.error( self.name + ": EOF exception found" )
3519 main.log.error( self.name + ": " + self.handle.before )
3520 main.cleanup()
3521 main.exit()
3522 except Exception:
3523 main.log.exception( self.name + ": Uncaught exception!" )
3524 main.cleanup()
3525 main.exit()
3526
3527 def setCfg( self, component, propName, value=None, check=True ):
3528 """
3529 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003530 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003531 component - The case sensitive name of the component whose
3532 property is to be set
3533 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003534 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003535 value - The value to set the property to. If None, will unset the
3536 property and revert it to it's default value(if applicable)
3537 check - Boolean, Check whether the option was successfully set this
3538 only applies when a value is given.
3539 returns:
3540 main.TRUE on success or main.FALSE on failure. If check is False,
3541 will return main.TRUE unless there is an error
3542 """
3543 try:
3544 baseStr = "cfg"
3545 cmdStr = " set " + str( component ) + " " + str( propName )
3546 if value is not None:
3547 cmdStr += " " + str( value )
3548 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003549 assert "Command not found:" not in output, output
3550 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003551 if value and check:
3552 results = self.getCfg( component=str( component ),
3553 propName=str( propName ),
3554 jsonFormat=True )
3555 # Check if current value is what we just set
3556 try:
3557 jsonOutput = json.loads( results )
3558 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003559 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003560 main.log.exception( "Error parsing cfg output" )
3561 main.log.error( "output:" + repr( results ) )
3562 return main.FALSE
3563 if current == str( value ):
3564 return main.TRUE
3565 return main.FALSE
3566 return main.TRUE
3567 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003568 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003569 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003570 except ( TypeError, ValueError ):
3571 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003572 return main.FALSE
3573 except pexpect.EOF:
3574 main.log.error( self.name + ": EOF exception found" )
3575 main.log.error( self.name + ": " + self.handle.before )
3576 main.cleanup()
3577 main.exit()
3578 except Exception:
3579 main.log.exception( self.name + ": Uncaught exception!" )
3580 main.cleanup()
3581 main.exit()
3582
Jon Hall390696c2015-05-05 17:13:41 -07003583 def setTestAdd( self, setName, values ):
3584 """
3585 CLI command to add elements to a distributed set.
3586 Arguments:
3587 setName - The name of the set to add to.
3588 values - The value(s) to add to the set, space seperated.
3589 Example usages:
3590 setTestAdd( "set1", "a b c" )
3591 setTestAdd( "set2", "1" )
3592 returns:
3593 main.TRUE on success OR
3594 main.FALSE if elements were already in the set OR
3595 main.ERROR on error
3596 """
3597 try:
3598 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3599 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003600 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003601 try:
3602 # TODO: Maybe make this less hardcoded
3603 # ConsistentMap Exceptions
3604 assert "org.onosproject.store.service" not in output
3605 # Node not leader
3606 assert "java.lang.IllegalStateException" not in output
3607 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003608 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003609 "command: " + str( output ) )
3610 retryTime = 30 # Conservative time, given by Madan
3611 main.log.info( "Waiting " + str( retryTime ) +
3612 "seconds before retrying." )
3613 time.sleep( retryTime ) # Due to change in mastership
3614 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003615 assert "Error executing command" not in output
3616 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3617 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3618 main.log.info( self.name + ": " + output )
3619 if re.search( positiveMatch, output):
3620 return main.TRUE
3621 elif re.search( negativeMatch, output):
3622 return main.FALSE
3623 else:
3624 main.log.error( self.name + ": setTestAdd did not" +
3625 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003626 main.log.debug( self.name + " actual: " + repr( output ) )
3627 return main.ERROR
3628 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003629 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003630 return main.ERROR
3631 except TypeError:
3632 main.log.exception( self.name + ": Object not as expected" )
3633 return main.ERROR
3634 except pexpect.EOF:
3635 main.log.error( self.name + ": EOF exception found" )
3636 main.log.error( self.name + ": " + self.handle.before )
3637 main.cleanup()
3638 main.exit()
3639 except Exception:
3640 main.log.exception( self.name + ": Uncaught exception!" )
3641 main.cleanup()
3642 main.exit()
3643
3644 def setTestRemove( self, setName, values, clear=False, retain=False ):
3645 """
3646 CLI command to remove elements from a distributed set.
3647 Required arguments:
3648 setName - The name of the set to remove from.
3649 values - The value(s) to remove from the set, space seperated.
3650 Optional arguments:
3651 clear - Clear all elements from the set
3652 retain - Retain only the given values. (intersection of the
3653 original set and the given set)
3654 returns:
3655 main.TRUE on success OR
3656 main.FALSE if the set was not changed OR
3657 main.ERROR on error
3658 """
3659 try:
3660 cmdStr = "set-test-remove "
3661 if clear:
3662 cmdStr += "-c " + str( setName )
3663 elif retain:
3664 cmdStr += "-r " + str( setName ) + " " + str( values )
3665 else:
3666 cmdStr += str( setName ) + " " + str( values )
3667 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003668 try:
3669 # TODO: Maybe make this less hardcoded
3670 # ConsistentMap Exceptions
3671 assert "org.onosproject.store.service" not in output
3672 # Node not leader
3673 assert "java.lang.IllegalStateException" not in output
3674 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003675 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003676 "command: " + str( output ) )
3677 retryTime = 30 # Conservative time, given by Madan
3678 main.log.info( "Waiting " + str( retryTime ) +
3679 "seconds before retrying." )
3680 time.sleep( retryTime ) # Due to change in mastership
3681 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003682 assert "Command not found:" not in output, output
3683 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003684 main.log.info( self.name + ": " + output )
3685 if clear:
3686 pattern = "Set " + str( setName ) + " cleared"
3687 if re.search( pattern, output ):
3688 return main.TRUE
3689 elif retain:
3690 positivePattern = str( setName ) + " was pruned to contain " +\
3691 "only elements of set \[(.*)\]"
3692 negativePattern = str( setName ) + " was not changed by " +\
3693 "retaining only elements of the set " +\
3694 "\[(.*)\]"
3695 if re.search( positivePattern, output ):
3696 return main.TRUE
3697 elif re.search( negativePattern, output ):
3698 return main.FALSE
3699 else:
3700 positivePattern = "\[(.*)\] was removed from the set " +\
3701 str( setName )
3702 if ( len( values.split() ) == 1 ):
3703 negativePattern = "\[(.*)\] was not in set " +\
3704 str( setName )
3705 else:
3706 negativePattern = "No element of \[(.*)\] was in set " +\
3707 str( setName )
3708 if re.search( positivePattern, output ):
3709 return main.TRUE
3710 elif re.search( negativePattern, output ):
3711 return main.FALSE
3712 main.log.error( self.name + ": setTestRemove did not" +
3713 " match expected output" )
3714 main.log.debug( self.name + " expected: " + pattern )
3715 main.log.debug( self.name + " actual: " + repr( output ) )
3716 return main.ERROR
3717 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003718 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003719 return main.ERROR
3720 except TypeError:
3721 main.log.exception( self.name + ": Object not as expected" )
3722 return main.ERROR
3723 except pexpect.EOF:
3724 main.log.error( self.name + ": EOF exception found" )
3725 main.log.error( self.name + ": " + self.handle.before )
3726 main.cleanup()
3727 main.exit()
3728 except Exception:
3729 main.log.exception( self.name + ": Uncaught exception!" )
3730 main.cleanup()
3731 main.exit()
3732
3733 def setTestGet( self, setName, values="" ):
3734 """
3735 CLI command to get the elements in a distributed set.
3736 Required arguments:
3737 setName - The name of the set to remove from.
3738 Optional arguments:
3739 values - The value(s) to check if in the set, space seperated.
3740 returns:
3741 main.ERROR on error OR
3742 A list of elements in the set if no optional arguments are
3743 supplied OR
3744 A tuple containing the list then:
3745 main.FALSE if the given values are not in the set OR
3746 main.TRUE if the given values are in the set OR
3747 """
3748 try:
3749 values = str( values ).strip()
3750 setName = str( setName ).strip()
3751 length = len( values.split() )
3752 containsCheck = None
3753 # Patterns to match
3754 setPattern = "\[(.*)\]"
3755 pattern = "Items in set " + setName + ":\n" + setPattern
3756 containsTrue = "Set " + setName + " contains the value " + values
3757 containsFalse = "Set " + setName + " did not contain the value " +\
3758 values
3759 containsAllTrue = "Set " + setName + " contains the the subset " +\
3760 setPattern
3761 containsAllFalse = "Set " + setName + " did not contain the the" +\
3762 " subset " + setPattern
3763
3764 cmdStr = "set-test-get "
3765 cmdStr += setName + " " + values
3766 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003767 try:
3768 # TODO: Maybe make this less hardcoded
3769 # ConsistentMap Exceptions
3770 assert "org.onosproject.store.service" not in output
3771 # Node not leader
3772 assert "java.lang.IllegalStateException" not in output
3773 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003774 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003775 "command: " + str( output ) )
3776 retryTime = 30 # Conservative time, given by Madan
3777 main.log.info( "Waiting " + str( retryTime ) +
3778 "seconds before retrying." )
3779 time.sleep( retryTime ) # Due to change in mastership
3780 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003781 assert "Command not found:" not in output, output
3782 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003783 main.log.info( self.name + ": " + output )
3784
3785 if length == 0:
3786 match = re.search( pattern, output )
3787 else: # if given values
3788 if length == 1: # Contains output
3789 patternTrue = pattern + "\n" + containsTrue
3790 patternFalse = pattern + "\n" + containsFalse
3791 else: # ContainsAll output
3792 patternTrue = pattern + "\n" + containsAllTrue
3793 patternFalse = pattern + "\n" + containsAllFalse
3794 matchTrue = re.search( patternTrue, output )
3795 matchFalse = re.search( patternFalse, output )
3796 if matchTrue:
3797 containsCheck = main.TRUE
3798 match = matchTrue
3799 elif matchFalse:
3800 containsCheck = main.FALSE
3801 match = matchFalse
3802 else:
3803 main.log.error( self.name + " setTestGet did not match " +\
3804 "expected output" )
3805 main.log.debug( self.name + " expected: " + pattern )
3806 main.log.debug( self.name + " actual: " + repr( output ) )
3807 match = None
3808 if match:
3809 setMatch = match.group( 1 )
3810 if setMatch == '':
3811 setList = []
3812 else:
3813 setList = setMatch.split( ", " )
3814 if length > 0:
3815 return ( setList, containsCheck )
3816 else:
3817 return setList
3818 else: # no match
3819 main.log.error( self.name + ": setTestGet did not" +
3820 " match expected output" )
3821 main.log.debug( self.name + " expected: " + pattern )
3822 main.log.debug( self.name + " actual: " + repr( output ) )
3823 return main.ERROR
3824 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003825 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003826 return main.ERROR
3827 except TypeError:
3828 main.log.exception( self.name + ": Object not as expected" )
3829 return main.ERROR
3830 except pexpect.EOF:
3831 main.log.error( self.name + ": EOF exception found" )
3832 main.log.error( self.name + ": " + self.handle.before )
3833 main.cleanup()
3834 main.exit()
3835 except Exception:
3836 main.log.exception( self.name + ": Uncaught exception!" )
3837 main.cleanup()
3838 main.exit()
3839
3840 def setTestSize( self, setName ):
3841 """
3842 CLI command to get the elements in a distributed set.
3843 Required arguments:
3844 setName - The name of the set to remove from.
3845 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003846 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003847 None on error
3848 """
3849 try:
3850 # TODO: Should this check against the number of elements returned
3851 # and then return true/false based on that?
3852 setName = str( setName ).strip()
3853 # Patterns to match
3854 setPattern = "\[(.*)\]"
3855 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3856 setPattern
3857 cmdStr = "set-test-get -s "
3858 cmdStr += setName
3859 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003860 try:
3861 # TODO: Maybe make this less hardcoded
3862 # ConsistentMap Exceptions
3863 assert "org.onosproject.store.service" not in output
3864 # Node not leader
3865 assert "java.lang.IllegalStateException" not in output
3866 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003867 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003868 "command: " + str( output ) )
3869 retryTime = 30 # Conservative time, given by Madan
3870 main.log.info( "Waiting " + str( retryTime ) +
3871 "seconds before retrying." )
3872 time.sleep( retryTime ) # Due to change in mastership
3873 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003874 assert "Command not found:" not in output, output
3875 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003876 main.log.info( self.name + ": " + output )
3877 match = re.search( pattern, output )
3878 if match:
3879 setSize = int( match.group( 1 ) )
3880 setMatch = match.group( 2 )
3881 if len( setMatch.split() ) == setSize:
3882 main.log.info( "The size returned by " + self.name +
3883 " matches the number of elements in " +
3884 "the returned set" )
3885 else:
3886 main.log.error( "The size returned by " + self.name +
3887 " does not match the number of " +
3888 "elements in the returned set." )
3889 return setSize
3890 else: # no match
3891 main.log.error( self.name + ": setTestGet did not" +
3892 " match expected output" )
3893 main.log.debug( self.name + " expected: " + pattern )
3894 main.log.debug( self.name + " actual: " + repr( output ) )
3895 return None
3896 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003897 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003898 return None
Jon Hall390696c2015-05-05 17:13:41 -07003899 except TypeError:
3900 main.log.exception( self.name + ": Object not as expected" )
3901 return None
3902 except pexpect.EOF:
3903 main.log.error( self.name + ": EOF exception found" )
3904 main.log.error( self.name + ": " + self.handle.before )
3905 main.cleanup()
3906 main.exit()
3907 except Exception:
3908 main.log.exception( self.name + ": Uncaught exception!" )
3909 main.cleanup()
3910 main.exit()
3911
Jon Hall80daded2015-05-27 16:07:00 -07003912 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003913 """
3914 Command to list the various counters in the system.
3915 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003916 if jsonFormat, a string of the json object returned by the cli
3917 command
3918 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003919 None on error
3920 """
Jon Hall390696c2015-05-05 17:13:41 -07003921 try:
3922 counters = {}
3923 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003924 if jsonFormat:
3925 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003926 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003927 assert "Command not found:" not in output, output
3928 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003929 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003930 return output
Jon Hall390696c2015-05-05 17:13:41 -07003931 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003932 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003933 return None
Jon Hall390696c2015-05-05 17:13:41 -07003934 except TypeError:
3935 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003936 return None
Jon Hall390696c2015-05-05 17:13:41 -07003937 except pexpect.EOF:
3938 main.log.error( self.name + ": EOF exception found" )
3939 main.log.error( self.name + ": " + self.handle.before )
3940 main.cleanup()
3941 main.exit()
3942 except Exception:
3943 main.log.exception( self.name + ": Uncaught exception!" )
3944 main.cleanup()
3945 main.exit()
3946
Jon Halle1a3b752015-07-22 13:02:46 -07003947 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003948 """
Jon Halle1a3b752015-07-22 13:02:46 -07003949 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003950 Required arguments:
3951 counter - The name of the counter to increment.
3952 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003953 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003954 inMemory - use in memory map for the counter
3955 returns:
3956 integer value of the counter or
3957 None on Error
3958 """
3959 try:
3960 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003961 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003962 cmdStr = "counter-test-increment "
3963 if inMemory:
3964 cmdStr += "-i "
3965 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003966 if delta != 1:
3967 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003968 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003969 try:
3970 # TODO: Maybe make this less hardcoded
3971 # ConsistentMap Exceptions
3972 assert "org.onosproject.store.service" not in output
3973 # Node not leader
3974 assert "java.lang.IllegalStateException" not in output
3975 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003976 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003977 "command: " + str( output ) )
3978 retryTime = 30 # Conservative time, given by Madan
3979 main.log.info( "Waiting " + str( retryTime ) +
3980 "seconds before retrying." )
3981 time.sleep( retryTime ) # Due to change in mastership
3982 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003983 assert "Command not found:" not in output, output
3984 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003985 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003986 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003987 match = re.search( pattern, output )
3988 if match:
3989 return int( match.group( 1 ) )
3990 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003991 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003992 " match expected output." )
3993 main.log.debug( self.name + " expected: " + pattern )
3994 main.log.debug( self.name + " actual: " + repr( output ) )
3995 return None
3996 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003997 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003998 return None
3999 except TypeError:
4000 main.log.exception( self.name + ": Object not as expected" )
4001 return None
4002 except pexpect.EOF:
4003 main.log.error( self.name + ": EOF exception found" )
4004 main.log.error( self.name + ": " + self.handle.before )
4005 main.cleanup()
4006 main.exit()
4007 except Exception:
4008 main.log.exception( self.name + ": Uncaught exception!" )
4009 main.cleanup()
4010 main.exit()
4011
Jon Halle1a3b752015-07-22 13:02:46 -07004012 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4013 """
4014 CLI command to get a distributed counter then add a delta to it.
4015 Required arguments:
4016 counter - The name of the counter to increment.
4017 Optional arguments:
4018 delta - The long to add to the counter
4019 inMemory - use in memory map for the counter
4020 returns:
4021 integer value of the counter or
4022 None on Error
4023 """
4024 try:
4025 counter = str( counter )
4026 delta = int( delta )
4027 cmdStr = "counter-test-increment -g "
4028 if inMemory:
4029 cmdStr += "-i "
4030 cmdStr += counter
4031 if delta != 1:
4032 cmdStr += " " + str( delta )
4033 output = self.sendline( cmdStr )
4034 try:
4035 # TODO: Maybe make this less hardcoded
4036 # ConsistentMap Exceptions
4037 assert "org.onosproject.store.service" not in output
4038 # Node not leader
4039 assert "java.lang.IllegalStateException" not in output
4040 except AssertionError:
4041 main.log.error( "Error in processing '" + cmdStr + "' " +
4042 "command: " + str( output ) )
4043 retryTime = 30 # Conservative time, given by Madan
4044 main.log.info( "Waiting " + str( retryTime ) +
4045 "seconds before retrying." )
4046 time.sleep( retryTime ) # Due to change in mastership
4047 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004048 assert "Command not found:" not in output, output
4049 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004050 main.log.info( self.name + ": " + output )
4051 pattern = counter + " was updated to (-?\d+)"
4052 match = re.search( pattern, output )
4053 if match:
4054 return int( match.group( 1 ) )
4055 else:
4056 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4057 " match expected output." )
4058 main.log.debug( self.name + " expected: " + pattern )
4059 main.log.debug( self.name + " actual: " + repr( output ) )
4060 return None
4061 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004062 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004063 return None
4064 except TypeError:
4065 main.log.exception( self.name + ": Object not as expected" )
4066 return None
4067 except pexpect.EOF:
4068 main.log.error( self.name + ": EOF exception found" )
4069 main.log.error( self.name + ": " + self.handle.before )
4070 main.cleanup()
4071 main.exit()
4072 except Exception:
4073 main.log.exception( self.name + ": Uncaught exception!" )
4074 main.cleanup()
4075 main.exit()
4076
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004077 def summary( self, jsonFormat=True ):
4078 """
4079 Description: Execute summary command in onos
4080 Returns: json object ( summary -j ), returns main.FALSE if there is
4081 no output
4082
4083 """
4084 try:
4085 cmdStr = "summary"
4086 if jsonFormat:
4087 cmdStr += " -j"
4088 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004089 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004090 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004091 if not handle:
4092 main.log.error( self.name + ": There is no output in " +
4093 "summary command" )
4094 return main.FALSE
4095 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004096 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004097 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004098 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004099 except TypeError:
4100 main.log.exception( self.name + ": Object not as expected" )
4101 return None
4102 except pexpect.EOF:
4103 main.log.error( self.name + ": EOF exception found" )
4104 main.log.error( self.name + ": " + self.handle.before )
4105 main.cleanup()
4106 main.exit()
4107 except Exception:
4108 main.log.exception( self.name + ": Uncaught exception!" )
4109 main.cleanup()
4110 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004111
4112 def transactionalMapGet( self, keyName, inMemory=False ):
4113 """
4114 CLI command to get the value of a key in a consistent map using
4115 transactions. This a test function and can only get keys from the
4116 test map hard coded into the cli command
4117 Required arguments:
4118 keyName - The name of the key to get
4119 Optional arguments:
4120 inMemory - use in memory map for the counter
4121 returns:
4122 The string value of the key or
4123 None on Error
4124 """
4125 try:
4126 keyName = str( keyName )
4127 cmdStr = "transactional-map-test-get "
4128 if inMemory:
4129 cmdStr += "-i "
4130 cmdStr += keyName
4131 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004132 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004133 try:
4134 # TODO: Maybe make this less hardcoded
4135 # ConsistentMap Exceptions
4136 assert "org.onosproject.store.service" not in output
4137 # Node not leader
4138 assert "java.lang.IllegalStateException" not in output
4139 except AssertionError:
4140 main.log.error( "Error in processing '" + cmdStr + "' " +
4141 "command: " + str( output ) )
4142 return None
4143 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4144 if "Key " + keyName + " not found." in output:
4145 return None
4146 else:
4147 match = re.search( pattern, output )
4148 if match:
4149 return match.groupdict()[ 'value' ]
4150 else:
4151 main.log.error( self.name + ": transactionlMapGet did not" +
4152 " match expected output." )
4153 main.log.debug( self.name + " expected: " + pattern )
4154 main.log.debug( self.name + " actual: " + repr( output ) )
4155 return None
Jon Hallc6793552016-01-19 14:18:37 -08004156 except AssertionError:
4157 main.log.exception( "" )
4158 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004159 except TypeError:
4160 main.log.exception( self.name + ": Object not as expected" )
4161 return None
4162 except pexpect.EOF:
4163 main.log.error( self.name + ": EOF exception found" )
4164 main.log.error( self.name + ": " + self.handle.before )
4165 main.cleanup()
4166 main.exit()
4167 except Exception:
4168 main.log.exception( self.name + ": Uncaught exception!" )
4169 main.cleanup()
4170 main.exit()
4171
4172 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4173 """
4174 CLI command to put a value into 'numKeys' number of keys in a
4175 consistent map using transactions. This a test function and can only
4176 put into keys named 'Key#' of the test map hard coded into the cli command
4177 Required arguments:
4178 numKeys - Number of keys to add the value to
4179 value - The string value to put into the keys
4180 Optional arguments:
4181 inMemory - use in memory map for the counter
4182 returns:
4183 A dictionary whose keys are the name of the keys put into the map
4184 and the values of the keys are dictionaries whose key-values are
4185 'value': value put into map and optionaly
4186 'oldValue': Previous value in the key or
4187 None on Error
4188
4189 Example output
4190 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4191 'Key2': {'value': 'Testing'} }
4192 """
4193 try:
4194 numKeys = str( numKeys )
4195 value = str( value )
4196 cmdStr = "transactional-map-test-put "
4197 if inMemory:
4198 cmdStr += "-i "
4199 cmdStr += numKeys + " " + value
4200 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004201 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004202 try:
4203 # TODO: Maybe make this less hardcoded
4204 # ConsistentMap Exceptions
4205 assert "org.onosproject.store.service" not in output
4206 # Node not leader
4207 assert "java.lang.IllegalStateException" not in output
4208 except AssertionError:
4209 main.log.error( "Error in processing '" + cmdStr + "' " +
4210 "command: " + str( output ) )
4211 return None
4212 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4213 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4214 results = {}
4215 for line in output.splitlines():
4216 new = re.search( newPattern, line )
4217 updated = re.search( updatedPattern, line )
4218 if new:
4219 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4220 elif updated:
4221 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004222 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004223 else:
4224 main.log.error( self.name + ": transactionlMapGet did not" +
4225 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004226 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4227 newPattern,
4228 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004229 main.log.debug( self.name + " actual: " + repr( output ) )
4230 return results
Jon Hallc6793552016-01-19 14:18:37 -08004231 except AssertionError:
4232 main.log.exception( "" )
4233 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004234 except TypeError:
4235 main.log.exception( self.name + ": Object not as expected" )
4236 return None
4237 except pexpect.EOF:
4238 main.log.error( self.name + ": EOF exception found" )
4239 main.log.error( self.name + ": " + self.handle.before )
4240 main.cleanup()
4241 main.exit()
4242 except Exception:
4243 main.log.exception( self.name + ": Uncaught exception!" )
4244 main.cleanup()
4245 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004246
acsmarsdaea66c2015-09-03 11:44:06 -07004247 def maps( self, jsonFormat=True ):
4248 """
4249 Description: Returns result of onos:maps
4250 Optional:
4251 * jsonFormat: enable json formatting of output
4252 """
4253 try:
4254 cmdStr = "maps"
4255 if jsonFormat:
4256 cmdStr += " -j"
4257 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004258 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004259 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004260 except AssertionError:
4261 main.log.exception( "" )
4262 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004263 except TypeError:
4264 main.log.exception( self.name + ": Object not as expected" )
4265 return None
4266 except pexpect.EOF:
4267 main.log.error( self.name + ": EOF exception found" )
4268 main.log.error( self.name + ": " + self.handle.before )
4269 main.cleanup()
4270 main.exit()
4271 except Exception:
4272 main.log.exception( self.name + ": Uncaught exception!" )
4273 main.cleanup()
4274 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004275
4276 def getSwController( self, uri, jsonFormat=True ):
4277 """
4278 Descrition: Gets the controller information from the device
4279 """
4280 try:
4281 cmd = "device-controllers "
4282 if jsonFormat:
4283 cmd += "-j "
4284 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004285 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004286 return response
Jon Hallc6793552016-01-19 14:18:37 -08004287 except AssertionError:
4288 main.log.exception( "" )
4289 return None
GlennRC050596c2015-11-18 17:06:41 -08004290 except TypeError:
4291 main.log.exception( self.name + ": Object not as expected" )
4292 return None
4293 except pexpect.EOF:
4294 main.log.error( self.name + ": EOF exception found" )
4295 main.log.error( self.name + ": " + self.handle.before )
4296 main.cleanup()
4297 main.exit()
4298 except Exception:
4299 main.log.exception( self.name + ": Uncaught exception!" )
4300 main.cleanup()
4301 main.exit()
4302
4303 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4304 """
4305 Descrition: sets the controller(s) for the specified device
4306
4307 Parameters:
4308 Required: uri - String: The uri of the device(switch).
4309 ip - String or List: The ip address of the controller.
4310 This parameter can be formed in a couple of different ways.
4311 VALID:
4312 10.0.0.1 - just the ip address
4313 tcp:10.0.0.1 - the protocol and the ip address
4314 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4315 so that you can add controllers with different
4316 protocols and ports
4317 INVALID:
4318 10.0.0.1:6653 - this is not supported by ONOS
4319
4320 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4321 port - The port number.
4322 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4323
4324 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4325 """
4326 try:
4327 cmd = "device-setcontrollers"
4328
4329 if jsonFormat:
4330 cmd += " -j"
4331 cmd += " " + uri
4332 if isinstance( ip, str ):
4333 ip = [ip]
4334 for item in ip:
4335 if ":" in item:
4336 sitem = item.split( ":" )
4337 if len(sitem) == 3:
4338 cmd += " " + item
4339 elif "." in sitem[1]:
4340 cmd += " {}:{}".format(item, port)
4341 else:
4342 main.log.error( "Malformed entry: " + item )
4343 raise TypeError
4344 else:
4345 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004346 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004347 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004348 if "Error" in response:
4349 main.log.error( response )
4350 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004351 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004352 except AssertionError:
4353 main.log.exception( "" )
4354 return None
GlennRC050596c2015-11-18 17:06:41 -08004355 except TypeError:
4356 main.log.exception( self.name + ": Object not as expected" )
4357 return main.FALSE
4358 except pexpect.EOF:
4359 main.log.error( self.name + ": EOF exception found" )
4360 main.log.error( self.name + ": " + self.handle.before )
4361 main.cleanup()
4362 main.exit()
4363 except Exception:
4364 main.log.exception( self.name + ": Uncaught exception!" )
4365 main.cleanup()
4366 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004367
4368 def removeDevice( self, device ):
4369 '''
4370 Description:
4371 Remove a device from ONOS by passing the uri of the device(s).
4372 Parameters:
4373 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4374 Returns:
4375 Returns main.FALSE if an exception is thrown or an error is present
4376 in the response. Otherwise, returns main.TRUE.
4377 NOTE:
4378 If a host cannot be removed, then this function will return main.FALSE
4379 '''
4380 try:
4381 if type( device ) is str:
4382 device = list( device )
4383
4384 for d in device:
4385 time.sleep( 1 )
4386 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004387 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004388 if "Error" in response:
4389 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4390 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004391 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004392 except AssertionError:
4393 main.log.exception( "" )
4394 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004395 except TypeError:
4396 main.log.exception( self.name + ": Object not as expected" )
4397 return main.FALSE
4398 except pexpect.EOF:
4399 main.log.error( self.name + ": EOF exception found" )
4400 main.log.error( self.name + ": " + self.handle.before )
4401 main.cleanup()
4402 main.exit()
4403 except Exception:
4404 main.log.exception( self.name + ": Uncaught exception!" )
4405 main.cleanup()
4406 main.exit()
4407
4408 def removeHost( self, host ):
4409 '''
4410 Description:
4411 Remove a host from ONOS by passing the id of the host(s)
4412 Parameters:
4413 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4414 Returns:
4415 Returns main.FALSE if an exception is thrown or an error is present
4416 in the response. Otherwise, returns main.TRUE.
4417 NOTE:
4418 If a host cannot be removed, then this function will return main.FALSE
4419 '''
4420 try:
4421 if type( host ) is str:
4422 host = list( host )
4423
4424 for h in host:
4425 time.sleep( 1 )
4426 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004427 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004428 if "Error" in response:
4429 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4430 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004431 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004432 except AssertionError:
4433 main.log.exception( "" )
4434 return None
GlennRC20fc6522015-12-23 23:26:57 -08004435 except TypeError:
4436 main.log.exception( self.name + ": Object not as expected" )
4437 return main.FALSE
4438 except pexpect.EOF:
4439 main.log.error( self.name + ": EOF exception found" )
4440 main.log.error( self.name + ": " + self.handle.before )
4441 main.cleanup()
4442 main.exit()
4443 except Exception:
4444 main.log.exception( self.name + ": Uncaught exception!" )
4445 main.cleanup()
4446 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004447
Jon Hallc6793552016-01-19 14:18:37 -08004448 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004449 '''
4450 Description:
4451 Bring link down or up in the null-provider.
4452 params:
4453 begin - (string) One end of a device or switch.
4454 end - (string) the other end of the device or switch
4455 returns:
4456 main.TRUE if no exceptions were thrown and no Errors are
4457 present in the resoponse. Otherwise, returns main.FALSE
4458 '''
4459 try:
Jon Hallc6793552016-01-19 14:18:37 -08004460 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004461 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004462 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004463 if "Error" in response or "Failure" in response:
4464 main.log.error( response )
4465 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004466 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004467 except AssertionError:
4468 main.log.exception( "" )
4469 return None
GlennRCed771242016-01-13 17:02:47 -08004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return main.FALSE
4473 except pexpect.EOF:
4474 main.log.error( self.name + ": EOF exception found" )
4475 main.log.error( self.name + ": " + self.handle.before )
4476 main.cleanup()
4477 main.exit()
4478 except Exception:
4479 main.log.exception( self.name + ": Uncaught exception!" )
4480 main.cleanup()
4481 main.exit()
4482