blob: f77ad8fb85ca953a0e7a6459226457c3d104a5ab [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:
Jon Hallff566d52016-01-15 14:45:36 -08001869 main.log.error( handle )
pingping-lin8244a3b2015-09-16 13:36:56 -07001870 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001871 except AssertionError:
1872 main.log.exception( "" )
1873 return None
1874 except ( TypeError, ValueError ):
1875 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001876 return None
1877 except pexpect.EOF:
1878 main.log.error( self.name + ": EOF exception found" )
1879 main.log.error( self.name + ": " + self.handle.before )
1880 main.cleanup()
1881 main.exit()
1882 except Exception:
1883 main.log.exception( self.name + ": Uncaught exception!" )
1884 main.cleanup()
1885 main.exit()
1886
kelvin-onlab54400a92015-02-26 18:05:51 -08001887 def getIntentState(self, intentsId, intentsJson=None):
1888 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001889 Check intent state.
1890 Accepts a single intent ID (string type) or a list of intent IDs.
1891 Returns the state(string type) of the id if a single intent ID is
1892 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001893 Returns a dictionary with intent IDs as the key and its
1894 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001895 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001896 intentId: intent ID (string type)
1897 intentsJson: parsed json object from the onos:intents api
1898 Returns:
1899 state = An intent's state- INSTALL,WITHDRAWN etc.
1900 stateDict = Dictionary of intent's state. intent ID as the keys and
1901 state as the values.
1902 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001903 try:
1904 state = "State is Undefined"
1905 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001906 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001907 else:
Jon Hallc6793552016-01-19 14:18:37 -08001908 rawJson = intentsJson
1909 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001910 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001911 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001912 if intentsId == intent[ 'id' ]:
1913 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001914 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001915 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1916 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001917 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001918 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001919 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001920 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001921 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001922 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001923 if intentsId[ i ] == intents[ 'id' ]:
1924 stateDict[ 'state' ] = intents[ 'state' ]
1925 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001926 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001927 break
Jon Hallefbd9792015-03-05 16:11:36 -08001928 if len( intentsId ) != len( dictList ):
1929 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001930 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001931 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001932 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001933 return None
Jon Hallc6793552016-01-19 14:18:37 -08001934 except ( TypeError, ValueError ):
1935 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001936 return None
1937 except pexpect.EOF:
1938 main.log.error( self.name + ": EOF exception found" )
1939 main.log.error( self.name + ": " + self.handle.before )
1940 main.cleanup()
1941 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001942 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001943 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001944 main.cleanup()
1945 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001946
kelvin-onlabf512e942015-06-08 19:42:59 -07001947 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001948 """
1949 Description:
1950 Check intents state
1951 Required:
1952 intentsId - List of intents ID to be checked
1953 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001954 expectedState - Check the expected state(s) of each intents
1955 state in the list.
1956 *NOTE: You can pass in a list of expected state,
1957 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001958 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001959 Returns main.TRUE only if all intent are the same as expected states
1960 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001961 """
1962 try:
1963 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001964 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001965 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001966 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08001967 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001968 "getting intents state" )
1969 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001970
1971 if isinstance( expectedState, types.StringType ):
1972 for intents in intentsDict:
1973 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001974 main.log.debug( self.name + " : Intent ID - " +
1975 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001976 " actual state = " +
1977 intents.get( 'state' )
1978 + " does not equal expected state = "
1979 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001980 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001981
1982 elif isinstance( expectedState, types.ListType ):
1983 for intents in intentsDict:
1984 if not any( state == intents.get( 'state' ) for state in
1985 expectedState ):
1986 main.log.debug( self.name + " : Intent ID - " +
1987 intents.get( 'id' ) +
1988 " actual state = " +
1989 intents.get( 'state' ) +
1990 " does not equal expected states = "
1991 + str( expectedState ) )
1992 returnValue = main.FALSE
1993
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001994 if returnValue == main.TRUE:
1995 main.log.info( self.name + ": All " +
1996 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001997 " intents are in " + str( expectedState ) +
1998 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001999 return returnValue
2000 except TypeError:
2001 main.log.exception( self.name + ": Object not as expected" )
2002 return None
2003 except pexpect.EOF:
2004 main.log.error( self.name + ": EOF exception found" )
2005 main.log.error( self.name + ": " + self.handle.before )
2006 main.cleanup()
2007 main.exit()
2008 except Exception:
2009 main.log.exception( self.name + ": Uncaught exception!" )
2010 main.cleanup()
2011 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002012
GlennRCed771242016-01-13 17:02:47 -08002013 def checkIntentSummary( self, timeout=60 ):
2014 """
2015 Description:
2016 Check the number of installed intents.
2017 Optional:
2018 timeout - the timeout for pexcept
2019 Return:
2020 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2021 , otherwise, returns main.FALSE.
2022 """
2023
2024 try:
2025 cmd = "intents -s -j"
2026
2027 # Check response if something wrong
2028 response = self.sendline( cmd, timeout=timeout )
2029 if response == None:
2030 return main.False
2031 response = json.loads( response )
2032
2033 # get total and installed number, see if they are match
2034 allState = response.get( 'all' )
2035 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002036 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002037 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002038 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002039 return main.FALSE
2040
Jon Hallc6793552016-01-19 14:18:37 -08002041 except ( TypeError, ValueError ):
2042 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002043 return None
2044 except pexpect.EOF:
2045 main.log.error( self.name + ": EOF exception found" )
2046 main.log.error( self.name + ": " + self.handle.before )
2047 main.cleanup()
2048 main.exit()
2049 except Exception:
2050 main.log.exception( self.name + ": Uncaught exception!" )
2051 main.cleanup()
2052 main.exit()
2053
2054 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002055 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002056 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002057 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002058 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002059 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002060 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002061 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002062 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002063 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002064 cmdStr += " -j "
2065 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002066 handle = self.sendline( cmdStr, timeout=timeout )
2067 assert "Command not found:" not in handle, handle
2068 if re.search( "Error:", handle ):
2069 main.log.error( self.name + ": flows() response: " +
2070 str( handle ) )
2071 return handle
2072 except AssertionError:
2073 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002074 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002075 except TypeError:
2076 main.log.exception( self.name + ": Object not as expected" )
2077 return None
Jon Hallc6793552016-01-19 14:18:37 -08002078 except pexpect.TIMEOUT:
2079 main.log.error( self.name + ": ONOS timeout" )
2080 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002081 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002082 main.log.error( self.name + ": EOF exception found" )
2083 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002084 main.cleanup()
2085 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002086 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002087 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002088 main.cleanup()
2089 main.exit()
2090
GlennRCed771242016-01-13 17:02:47 -08002091
Jon Hallc6793552016-01-19 14:18:37 -08002092 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002093 """
2094 Description:
GlennRCed771242016-01-13 17:02:47 -08002095 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002096 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2097 if the count of those states is 0, which means all current flows
2098 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002099 Optional:
GlennRCed771242016-01-13 17:02:47 -08002100 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002101 Return:
2102 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002103 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002104 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002105 """
2106 try:
GlennRCed771242016-01-13 17:02:47 -08002107 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2108 checkedStates = []
2109 statesCount = [0, 0, 0, 0]
2110 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002111 rawFlows = self.flows( state=s, timeout = timeout )
2112 checkedStates.append( json.loads( rawFlows ) )
2113 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002114 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002115 try:
2116 statesCount[i] += int( c.get( "flowCount" ) )
2117 except TypeError:
2118 main.log.exception( "Json object not as expected" )
2119 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002120
GlennRCed771242016-01-13 17:02:47 -08002121 # We want to count PENDING_ADD if isPENDING is true
2122 if isPENDING:
2123 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2124 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002125 else:
GlennRCed771242016-01-13 17:02:47 -08002126 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2127 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002128 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002129 except ( TypeError, ValueError ):
2130 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002131 return None
2132 except pexpect.EOF:
2133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
2135 main.cleanup()
2136 main.exit()
2137 except Exception:
2138 main.log.exception( self.name + ": Uncaught exception!" )
2139 main.cleanup()
2140 main.exit()
2141
GlennRCed771242016-01-13 17:02:47 -08002142 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2143 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002144 """
andrewonlab87852b02014-11-19 18:44:19 -05002145 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002146 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002147 a specific point-to-point intent definition
2148 Required:
GlennRCed771242016-01-13 17:02:47 -08002149 * ingress: specify source dpid
2150 * egress: specify destination dpid
2151 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002152 Optional:
GlennRCed771242016-01-13 17:02:47 -08002153 * offset: the keyOffset is where the next batch of intents
2154 will be installed
2155 Returns: If failed to push test intents, it will returen None,
2156 if successful, return true.
2157 Timeout expection will return None,
2158 TypeError will return false
2159 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002160 """
andrewonlab87852b02014-11-19 18:44:19 -05002161 try:
GlennRCed771242016-01-13 17:02:47 -08002162 if background:
2163 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002164 else:
GlennRCed771242016-01-13 17:02:47 -08002165 back = ""
2166 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002167 ingress,
2168 egress,
2169 batchSize,
2170 offset,
2171 back )
GlennRCed771242016-01-13 17:02:47 -08002172 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002173 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002174 main.log.info( response )
2175 if response == None:
2176 return None
2177
2178 # TODO: We should handle if there is failure in installation
2179 return main.TRUE
2180
Jon Hallc6793552016-01-19 14:18:37 -08002181 except AssertionError:
2182 main.log.exception( "" )
2183 return None
GlennRCed771242016-01-13 17:02:47 -08002184 except pexpect.TIMEOUT:
2185 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002186 return None
andrewonlab87852b02014-11-19 18:44:19 -05002187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002190 main.cleanup()
2191 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002192 except TypeError:
2193 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002194 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002196 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002197 main.cleanup()
2198 main.exit()
2199
YPZhangf6f14a02016-01-28 15:17:31 -08002200 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002201 """
2202 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002203 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002204 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002205 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002206 """
2207 try:
YPZhangf6f14a02016-01-28 15:17:31 -08002208 cmd = "flows -s|grep ADDED|wc -l"
2209 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002210 if response == None:
2211 return -1
YPZhangf6f14a02016-01-28 15:17:31 -08002212 return int( response )
YPZhangb5d3f832016-01-23 22:54:26 -08002213 except TypeError:
2214 main.log.exception( self.name + ": Object not as expected" )
2215 return None
2216 except pexpect.EOF:
2217 main.log.error( self.name + ": EOF exception found" )
2218 main.log.error( self.name + ": " + self.handle.before )
2219 main.cleanup()
2220 main.exit()
2221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception!" )
2223 main.cleanup()
2224 main.exit()
2225
2226 def getTotalIntentsNum( self ):
2227 """
2228 Description:
2229 Get the total number of intents, include every states.
2230 Return:
2231 The number of intents
2232 """
2233 try:
2234 cmd = "summary -j"
2235 response = self.sendline( cmd )
2236 if response == None:
2237 return -1
2238 response = json.loads( response )
2239 return int( response.get("intents") )
2240 except TypeError:
2241 main.log.exception( self.name + ": Object not as expected" )
2242 return None
2243 except pexpect.EOF:
2244 main.log.error( self.name + ": EOF exception found" )
2245 main.log.error( self.name + ": " + self.handle.before )
2246 main.cleanup()
2247 main.exit()
2248 except Exception:
2249 main.log.exception( self.name + ": Uncaught exception!" )
2250 main.cleanup()
2251 main.exit()
2252
kelvin-onlabd3b64892015-01-20 13:26:24 -08002253 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002254 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002255 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002256 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002257 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002258 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002259 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002260 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002261 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002262 cmdStr += " -j"
2263 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002264 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002265 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002266 except AssertionError:
2267 main.log.exception( "" )
2268 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002269 except TypeError:
2270 main.log.exception( self.name + ": Object not as expected" )
2271 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002272 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002273 main.log.error( self.name + ": EOF exception found" )
2274 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002275 main.cleanup()
2276 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002277 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002278 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002279 main.cleanup()
2280 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002281
kelvin-onlabd3b64892015-01-20 13:26:24 -08002282 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002283 """
2284 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002285 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002286 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002287 """
andrewonlab867212a2014-10-22 20:13:38 -04002288 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002289 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002291 cmdStr += " -j"
2292 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002293 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002294 if handle:
2295 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002296 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002297 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002298 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002299 else:
2300 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002301 except AssertionError:
2302 main.log.exception( "" )
2303 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002304 except TypeError:
2305 main.log.exception( self.name + ": Object not as expected" )
2306 return None
andrewonlab867212a2014-10-22 20:13:38 -04002307 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002308 main.log.error( self.name + ": EOF exception found" )
2309 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002310 main.cleanup()
2311 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002312 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002313 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002314 main.cleanup()
2315 main.exit()
2316
kelvin8ec71442015-01-15 16:57:00 -08002317 # Wrapper functions ****************
2318 # Wrapper functions use existing driver
2319 # functions and extends their use case.
2320 # For example, we may use the output of
2321 # a normal driver function, and parse it
2322 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002323
kelvin-onlabd3b64892015-01-20 13:26:24 -08002324 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002325 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002326 Description:
2327 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002328 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002329 try:
kelvin8ec71442015-01-15 16:57:00 -08002330 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002331 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002332 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002333
kelvin8ec71442015-01-15 16:57:00 -08002334 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002335 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2336 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002337 match = re.search('id=0x([\da-f]+),', intents)
2338 if match:
2339 tmpId = match.group()[3:-1]
2340 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002341 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002342
Jon Halld4d4b372015-01-28 16:02:41 -08002343 except TypeError:
2344 main.log.exception( self.name + ": Object not as expected" )
2345 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002346 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002347 main.log.error( self.name + ": EOF exception found" )
2348 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002349 main.cleanup()
2350 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002352 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002353 main.cleanup()
2354 main.exit()
2355
Jon Hall30b82fa2015-03-04 17:15:43 -08002356 def FlowAddedCount( self, deviceId ):
2357 """
2358 Determine the number of flow rules for the given device id that are
2359 in the added state
2360 """
2361 try:
2362 cmdStr = "flows any " + str( deviceId ) + " | " +\
2363 "grep 'state=ADDED' | wc -l"
2364 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002365 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002366 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002367 except AssertionError:
2368 main.log.exception( "" )
2369 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002370 except pexpect.EOF:
2371 main.log.error( self.name + ": EOF exception found" )
2372 main.log.error( self.name + ": " + self.handle.before )
2373 main.cleanup()
2374 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002375 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002376 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002377 main.cleanup()
2378 main.exit()
2379
kelvin-onlabd3b64892015-01-20 13:26:24 -08002380 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002381 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002382 Use 'devices' function to obtain list of all devices
2383 and parse the result to obtain a list of all device
2384 id's. Returns this list. Returns empty list if no
2385 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002386 List is ordered sequentially
2387
andrewonlab3e15ead2014-10-15 14:21:34 -04002388 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002389 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002390 the ids. By obtaining the list of device ids on the fly,
2391 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002392 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002393 try:
kelvin8ec71442015-01-15 16:57:00 -08002394 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002395 devicesStr = self.devices( jsonFormat=False )
2396 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002397
kelvin-onlabd3b64892015-01-20 13:26:24 -08002398 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002399 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002400 return idList
kelvin8ec71442015-01-15 16:57:00 -08002401
2402 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002403 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002404 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002405 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002406 # Split list further into arguments before and after string
2407 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002408 # append to idList
2409 for arg in tempList:
2410 idList.append( arg.split( "id=" )[ 1 ] )
2411 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002412
Jon Halld4d4b372015-01-28 16:02:41 -08002413 except TypeError:
2414 main.log.exception( self.name + ": Object not as expected" )
2415 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002417 main.log.error( self.name + ": EOF exception found" )
2418 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002419 main.cleanup()
2420 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002421 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002422 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002423 main.cleanup()
2424 main.exit()
2425
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002427 """
andrewonlab7c211572014-10-15 16:45:20 -04002428 Uses 'nodes' function to obtain list of all nodes
2429 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002430 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002431 Returns:
2432 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002433 """
andrewonlab7c211572014-10-15 16:45:20 -04002434 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002435 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002436 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002437 # Sample nodesStr output
2438 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002439 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002440 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002441 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002442 nodesJson = json.loads( nodesStr )
2443 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002444 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002445 except ( TypeError, ValueError ):
2446 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002447 return None
andrewonlab7c211572014-10-15 16:45:20 -04002448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002449 main.log.error( self.name + ": EOF exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002451 main.cleanup()
2452 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002454 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002455 main.cleanup()
2456 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002457
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002459 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002460 Return the first device from the devices api whose 'id' contains 'dpid'
2461 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002462 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002463 try:
kelvin8ec71442015-01-15 16:57:00 -08002464 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002465 return None
2466 else:
kelvin8ec71442015-01-15 16:57:00 -08002467 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002468 rawDevices = self.devices()
2469 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002470 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002472 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2473 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002474 return device
2475 return None
Jon Hallc6793552016-01-19 14:18:37 -08002476 except ( TypeError, ValueError ):
2477 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002478 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002479 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002480 main.log.error( self.name + ": EOF exception found" )
2481 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002482 main.cleanup()
2483 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002484 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002485 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002486 main.cleanup()
2487 main.exit()
2488
kelvin-onlabd3b64892015-01-20 13:26:24 -08002489 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002490 """
Jon Hallefbd9792015-03-05 16:11:36 -08002491 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002492 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002493 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002494
Jon Hall42db6dc2014-10-24 19:03:48 -04002495 Params: ip = ip used for the onos cli
2496 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002497 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002498 logLevel = level to log to. Currently accepts
2499 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002500
2501
kelvin-onlabd3b64892015-01-20 13:26:24 -08002502 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002503
Jon Hallefbd9792015-03-05 16:11:36 -08002504 Returns: main.TRUE if the number of switches and links are correct,
2505 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002506 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002507 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002508 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002509 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002510 if topology == {}:
2511 return main.ERROR
2512 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002513 # Is the number of switches is what we expected
2514 devices = topology.get( 'devices', False )
2515 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002516 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002517 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002518 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002519 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002520 linkCheck = ( int( links ) == int( numolink ) )
2521 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002522 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002523 output += "The number of links and switches match " +\
2524 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002525 result = main.TRUE
2526 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002527 output += "The number of links and switches does not match " +\
2528 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002529 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 output = output + "\n ONOS sees %i devices (%i expected) \
2531 and %i links (%i expected)" % (
2532 int( devices ), int( numoswitch ), int( links ),
2533 int( numolink ) )
2534 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002535 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002536 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002537 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002538 else:
Jon Hall390696c2015-05-05 17:13:41 -07002539 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002540 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002541 except TypeError:
2542 main.log.exception( self.name + ": Object not as expected" )
2543 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002545 main.log.error( self.name + ": EOF exception found" )
2546 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002547 main.cleanup()
2548 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002549 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002550 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002551 main.cleanup()
2552 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002553
kelvin-onlabd3b64892015-01-20 13:26:24 -08002554 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002555 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002556 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002557 deviceId must be the id of a device as seen in the onos devices command
2558 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002559 role must be either master, standby, or none
2560
Jon Halle3f39ff2015-01-13 11:50:53 -08002561 Returns:
2562 main.TRUE or main.FALSE based on argument verification and
2563 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002564 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002565 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002566 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002567 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 cmdStr = "device-role " +\
2569 str( deviceId ) + " " +\
2570 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002571 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002573 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002574 if re.search( "Error", handle ):
2575 # end color output to escape any colours
2576 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002577 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002578 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002579 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002580 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002581 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002582 main.log.error( "Invalid 'role' given to device_role(). " +
2583 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002584 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002585 except AssertionError:
2586 main.log.exception( "" )
2587 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002588 except TypeError:
2589 main.log.exception( self.name + ": Object not as expected" )
2590 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002592 main.log.error( self.name + ": EOF exception found" )
2593 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002594 main.cleanup()
2595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002597 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002598 main.cleanup()
2599 main.exit()
2600
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002602 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002603 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002604 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002605 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002606 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002607 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002608 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002609 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002610 cmdStr += " -j"
2611 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002612 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002613 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002614 except AssertionError:
2615 main.log.exception( "" )
2616 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002617 except TypeError:
2618 main.log.exception( self.name + ": Object not as expected" )
2619 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002620 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002621 main.log.error( self.name + ": EOF exception found" )
2622 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002623 main.cleanup()
2624 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002625 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002626 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002627 main.cleanup()
2628 main.exit()
2629
kelvin-onlabd3b64892015-01-20 13:26:24 -08002630 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002631 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002632 CLI command to get the current leader for the Election test application
2633 NOTE: Requires installation of the onos-app-election feature
2634 Returns: Node IP of the leader if one exists
2635 None if none exists
2636 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002637 """
Jon Hall94fd0472014-12-08 11:52:42 -08002638 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002639 cmdStr = "election-test-leader"
2640 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002641 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002642 # Leader
2643 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002644 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002645 nodeSearch = re.search( leaderPattern, response )
2646 if nodeSearch:
2647 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002648 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002649 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002650 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002651 # no leader
2652 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002653 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002654 nullSearch = re.search( nullPattern, response )
2655 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002656 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002657 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002658 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002659 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002660 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002661 if re.search( errorPattern, response ):
2662 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002663 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002664 return main.FALSE
2665 else:
Jon Hall390696c2015-05-05 17:13:41 -07002666 main.log.error( "Error in electionTestLeader on " + self.name +
2667 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002668 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002669 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002670 except AssertionError:
2671 main.log.exception( "" )
2672 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002673 except TypeError:
2674 main.log.exception( self.name + ": Object not as expected" )
2675 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002676 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002677 main.log.error( self.name + ": EOF exception found" )
2678 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002679 main.cleanup()
2680 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002681 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002682 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002683 main.cleanup()
2684 main.exit()
2685
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002687 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002688 CLI command to run for leadership of the Election test application.
2689 NOTE: Requires installation of the onos-app-election feature
2690 Returns: Main.TRUE on success
2691 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002692 """
Jon Hall94fd0472014-12-08 11:52:42 -08002693 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002694 cmdStr = "election-test-run"
2695 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002696 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002697 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002698 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002699 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002700 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002701 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002702 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002703 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002704 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002705 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002706 errorPattern = "Command\snot\sfound"
2707 if re.search( errorPattern, response ):
2708 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002709 return main.FALSE
2710 else:
Jon Hall390696c2015-05-05 17:13:41 -07002711 main.log.error( "Error in electionTestRun on " + self.name +
2712 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002713 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002714 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002715 except AssertionError:
2716 main.log.exception( "" )
2717 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002718 except TypeError:
2719 main.log.exception( self.name + ": Object not as expected" )
2720 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002721 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002722 main.log.error( self.name + ": EOF exception found" )
2723 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002724 main.cleanup()
2725 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002726 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002727 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002728 main.cleanup()
2729 main.exit()
2730
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002732 """
Jon Hall94fd0472014-12-08 11:52:42 -08002733 * CLI command to withdraw the local node from leadership election for
2734 * the Election test application.
2735 #NOTE: Requires installation of the onos-app-election feature
2736 Returns: Main.TRUE on success
2737 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002738 """
Jon Hall94fd0472014-12-08 11:52:42 -08002739 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002740 cmdStr = "election-test-withdraw"
2741 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002742 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002743 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002744 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002745 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002746 if re.search( successPattern, response ):
2747 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002748 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002749 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002750 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002751 errorPattern = "Command\snot\sfound"
2752 if re.search( errorPattern, response ):
2753 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002754 return main.FALSE
2755 else:
Jon Hall390696c2015-05-05 17:13:41 -07002756 main.log.error( "Error in electionTestWithdraw on " +
2757 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002758 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002759 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002760 except AssertionError:
2761 main.log.exception( "" )
2762 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002763 except TypeError:
2764 main.log.exception( self.name + ": Object not as expected" )
2765 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002769 main.cleanup()
2770 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002771 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002772 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002773 main.cleanup()
2774 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002775
kelvin8ec71442015-01-15 16:57:00 -08002776 def getDevicePortsEnabledCount( self, dpid ):
2777 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002778 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002779 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002780 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002781 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002782 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2783 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002784 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002785 if re.search( "No such device", output ):
2786 main.log.error( "Error in getting ports" )
2787 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002788 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002789 return output
Jon Hallc6793552016-01-19 14:18:37 -08002790 except AssertionError:
2791 main.log.exception( "" )
2792 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002793 except TypeError:
2794 main.log.exception( self.name + ": Object not as expected" )
2795 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002796 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002797 main.log.error( self.name + ": EOF exception found" )
2798 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002799 main.cleanup()
2800 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002801 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002802 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002803 main.cleanup()
2804 main.exit()
2805
kelvin8ec71442015-01-15 16:57:00 -08002806 def getDeviceLinksActiveCount( self, dpid ):
2807 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002808 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002809 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002810 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002811 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002812 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2813 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002814 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002815 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002816 main.log.error( "Error in getting ports " )
2817 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002818 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002819 return output
Jon Hallc6793552016-01-19 14:18:37 -08002820 except AssertionError:
2821 main.log.exception( "" )
2822 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002823 except TypeError:
2824 main.log.exception( self.name + ": Object not as expected" )
2825 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002826 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002827 main.log.error( self.name + ": EOF exception found" )
2828 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002829 main.cleanup()
2830 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002831 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002832 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002833 main.cleanup()
2834 main.exit()
2835
kelvin8ec71442015-01-15 16:57:00 -08002836 def getAllIntentIds( self ):
2837 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002838 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002839 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002840 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002841 cmdStr = "onos:intents | grep id="
2842 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002843 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002844 if re.search( "Error", output ):
2845 main.log.error( "Error in getting ports" )
2846 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002847 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002848 return output
Jon Hallc6793552016-01-19 14:18:37 -08002849 except AssertionError:
2850 main.log.exception( "" )
2851 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002852 except TypeError:
2853 main.log.exception( self.name + ": Object not as expected" )
2854 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002855 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002856 main.log.error( self.name + ": EOF exception found" )
2857 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002858 main.cleanup()
2859 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002860 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002861 main.log.exception( self.name + ": Uncaught exception!" )
2862 main.cleanup()
2863 main.exit()
2864
Jon Hall73509952015-02-24 16:42:56 -08002865 def intentSummary( self ):
2866 """
Jon Hallefbd9792015-03-05 16:11:36 -08002867 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002868 """
2869 try:
2870 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002871 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002872 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002873 states.append( intent.get( 'state', None ) )
2874 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002875 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002876 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002877 except ( TypeError, ValueError ):
2878 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002879 return None
2880 except pexpect.EOF:
2881 main.log.error( self.name + ": EOF exception found" )
2882 main.log.error( self.name + ": " + self.handle.before )
2883 main.cleanup()
2884 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002885 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002886 main.log.exception( self.name + ": Uncaught exception!" )
2887 main.cleanup()
2888 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002889
Jon Hall61282e32015-03-19 11:34:11 -07002890 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002891 """
2892 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002893 Optional argument:
2894 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002895 """
Jon Hall63604932015-02-26 17:09:50 -08002896 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002897 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002898 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002899 cmdStr += " -j"
2900 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002901 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002902 return output
Jon Hallc6793552016-01-19 14:18:37 -08002903 except AssertionError:
2904 main.log.exception( "" )
2905 return None
Jon Hall63604932015-02-26 17:09:50 -08002906 except TypeError:
2907 main.log.exception( self.name + ": Object not as expected" )
2908 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002909 except pexpect.EOF:
2910 main.log.error( self.name + ": EOF exception found" )
2911 main.log.error( self.name + ": " + self.handle.before )
2912 main.cleanup()
2913 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002914 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002915 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002916 main.cleanup()
2917 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002918
acsmarsa4a4d1e2015-07-10 16:01:24 -07002919 def leaderCandidates( self, jsonFormat=True ):
2920 """
2921 Returns the output of the leaders -c command.
2922 Optional argument:
2923 * jsonFormat - boolean indicating if you want output in json
2924 """
2925 try:
2926 cmdStr = "onos:leaders -c"
2927 if jsonFormat:
2928 cmdStr += " -j"
2929 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002930 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002931 return output
Jon Hallc6793552016-01-19 14:18:37 -08002932 except AssertionError:
2933 main.log.exception( "" )
2934 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002935 except TypeError:
2936 main.log.exception( self.name + ": Object not as expected" )
2937 return None
2938 except pexpect.EOF:
2939 main.log.error( self.name + ": EOF exception found" )
2940 main.log.error( self.name + ": " + self.handle.before )
2941 main.cleanup()
2942 main.exit()
2943 except Exception:
2944 main.log.exception( self.name + ": Uncaught exception!" )
2945 main.cleanup()
2946 main.exit()
2947
Jon Hallc6793552016-01-19 14:18:37 -08002948 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002949 """
2950 Returns a list in format [leader,candidate1,candidate2,...] for a given
2951 topic parameter and an empty list if the topic doesn't exist
2952 If no leader is elected leader in the returned list will be "none"
2953 Returns None if there is a type error processing the json object
2954 """
2955 try:
2956 cmdStr = "onos:leaders -c -j"
Jon Hallc6793552016-01-19 14:18:37 -08002957 rawOutput = self.sendline( cmdStr )
2958 assert "Command not found:" not in rawOutput, rawOutput
2959 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002960 results = []
2961 for dict in output:
2962 if dict["topic"] == topic:
2963 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002964 candidates = re.split( ", ", dict["candidates"][1:-1] )
2965 results.append( leader )
2966 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002967 return results
Jon Hallc6793552016-01-19 14:18:37 -08002968 except AssertionError:
2969 main.log.exception( "" )
2970 return None
2971 except ( TypeError, ValueError ):
2972 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002973 return None
2974 except pexpect.EOF:
2975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
2977 main.cleanup()
2978 main.exit()
2979 except Exception:
2980 main.log.exception( self.name + ": Uncaught exception!" )
2981 main.cleanup()
2982 main.exit()
2983
Jon Hall61282e32015-03-19 11:34:11 -07002984 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002985 """
2986 Returns the output of the intent Pending map.
2987 """
Jon Hall63604932015-02-26 17:09:50 -08002988 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002989 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002990 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002991 cmdStr += " -j"
2992 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002993 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002994 return output
Jon Hallc6793552016-01-19 14:18:37 -08002995 except AssertionError:
2996 main.log.exception( "" )
2997 return None
Jon Hall63604932015-02-26 17:09:50 -08002998 except TypeError:
2999 main.log.exception( self.name + ": Object not as expected" )
3000 return None
3001 except pexpect.EOF:
3002 main.log.error( self.name + ": EOF exception found" )
3003 main.log.error( self.name + ": " + self.handle.before )
3004 main.cleanup()
3005 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003006 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003007 main.log.exception( self.name + ": Uncaught exception!" )
3008 main.cleanup()
3009 main.exit()
3010
Jon Hall61282e32015-03-19 11:34:11 -07003011 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003012 """
3013 Returns the output of the raft partitions command for ONOS.
3014 """
Jon Hall61282e32015-03-19 11:34:11 -07003015 # Sample JSON
3016 # {
3017 # "leader": "tcp://10.128.30.11:7238",
3018 # "members": [
3019 # "tcp://10.128.30.11:7238",
3020 # "tcp://10.128.30.17:7238",
3021 # "tcp://10.128.30.13:7238",
3022 # ],
3023 # "name": "p1",
3024 # "term": 3
3025 # },
Jon Hall63604932015-02-26 17:09:50 -08003026 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003027 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003028 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003029 cmdStr += " -j"
3030 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003031 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003032 return output
Jon Hallc6793552016-01-19 14:18:37 -08003033 except AssertionError:
3034 main.log.exception( "" )
3035 return None
Jon Hall63604932015-02-26 17:09:50 -08003036 except TypeError:
3037 main.log.exception( self.name + ": Object not as expected" )
3038 return None
3039 except pexpect.EOF:
3040 main.log.error( self.name + ": EOF exception found" )
3041 main.log.error( self.name + ": " + self.handle.before )
3042 main.cleanup()
3043 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003044 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003045 main.log.exception( self.name + ": Uncaught exception!" )
3046 main.cleanup()
3047 main.exit()
3048
Jon Hallbe379602015-03-24 13:39:32 -07003049 def apps( self, jsonFormat=True ):
3050 """
3051 Returns the output of the apps command for ONOS. This command lists
3052 information about installed ONOS applications
3053 """
3054 # Sample JSON object
3055 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3056 # "description":"ONOS OpenFlow protocol southbound providers",
3057 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3058 # "features":"[onos-openflow]","state":"ACTIVE"}]
3059 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003060 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003061 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003062 cmdStr += " -j"
3063 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003064 assert "Command not found:" not in output, output
3065 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003066 return output
Jon Hallbe379602015-03-24 13:39:32 -07003067 # FIXME: look at specific exceptions/Errors
3068 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003069 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003070 return None
3071 except TypeError:
3072 main.log.exception( self.name + ": Object not as expected" )
3073 return None
3074 except pexpect.EOF:
3075 main.log.error( self.name + ": EOF exception found" )
3076 main.log.error( self.name + ": " + self.handle.before )
3077 main.cleanup()
3078 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003079 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003080 main.log.exception( self.name + ": Uncaught exception!" )
3081 main.cleanup()
3082 main.exit()
3083
Jon Hall146f1522015-03-24 15:33:24 -07003084 def appStatus( self, appName ):
3085 """
3086 Uses the onos:apps cli command to return the status of an application.
3087 Returns:
3088 "ACTIVE" - If app is installed and activated
3089 "INSTALLED" - If app is installed and deactivated
3090 "UNINSTALLED" - If app is not installed
3091 None - on error
3092 """
Jon Hall146f1522015-03-24 15:33:24 -07003093 try:
3094 if not isinstance( appName, types.StringType ):
3095 main.log.error( self.name + ".appStatus(): appName must be" +
3096 " a string" )
3097 return None
3098 output = self.apps( jsonFormat=True )
3099 appsJson = json.loads( output )
3100 state = None
3101 for app in appsJson:
3102 if appName == app.get('name'):
3103 state = app.get('state')
3104 break
3105 if state == "ACTIVE" or state == "INSTALLED":
3106 return state
3107 elif state is None:
3108 return "UNINSTALLED"
3109 elif state:
3110 main.log.error( "Unexpected state from 'onos:apps': " +
3111 str( state ) )
3112 return state
Jon Hallc6793552016-01-19 14:18:37 -08003113 except ( TypeError, ValueError ):
3114 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3115 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003116 return None
3117 except pexpect.EOF:
3118 main.log.error( self.name + ": EOF exception found" )
3119 main.log.error( self.name + ": " + self.handle.before )
3120 main.cleanup()
3121 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003122 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003123 main.log.exception( self.name + ": Uncaught exception!" )
3124 main.cleanup()
3125 main.exit()
3126
Jon Hallbe379602015-03-24 13:39:32 -07003127 def app( self, appName, option ):
3128 """
3129 Interacts with the app command for ONOS. This command manages
3130 application inventory.
3131 """
Jon Hallbe379602015-03-24 13:39:32 -07003132 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003133 # Validate argument types
3134 valid = True
3135 if not isinstance( appName, types.StringType ):
3136 main.log.error( self.name + ".app(): appName must be a " +
3137 "string" )
3138 valid = False
3139 if not isinstance( option, types.StringType ):
3140 main.log.error( self.name + ".app(): option must be a string" )
3141 valid = False
3142 if not valid:
3143 return main.FALSE
3144 # Validate Option
3145 option = option.lower()
3146 # NOTE: Install may become a valid option
3147 if option == "activate":
3148 pass
3149 elif option == "deactivate":
3150 pass
3151 elif option == "uninstall":
3152 pass
3153 else:
3154 # Invalid option
3155 main.log.error( "The ONOS app command argument only takes " +
3156 "the values: (activate|deactivate|uninstall)" +
3157 "; was given '" + option + "'")
3158 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003159 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003160 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003161 if "Error executing command" in output:
3162 main.log.error( "Error in processing onos:app command: " +
3163 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003164 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003165 elif "No such application" in output:
3166 main.log.error( "The application '" + appName +
3167 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003168 return main.FALSE
3169 elif "Command not found:" in output:
3170 main.log.error( "Error in processing onos:app command: " +
3171 str( output ) )
3172 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003173 elif "Unsupported command:" in output:
3174 main.log.error( "Incorrect command given to 'app': " +
3175 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003176 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003177 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003178 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003179 return main.TRUE
3180 except TypeError:
3181 main.log.exception( self.name + ": Object not as expected" )
3182 return main.ERROR
3183 except pexpect.EOF:
3184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
3186 main.cleanup()
3187 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003188 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003189 main.log.exception( self.name + ": Uncaught exception!" )
3190 main.cleanup()
3191 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003192
Jon Hallbd16b922015-03-26 17:53:15 -07003193 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003194 """
3195 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003196 appName is the hierarchical app name, not the feature name
3197 If check is True, method will check the status of the app after the
3198 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003199 Returns main.TRUE if the command was successfully sent
3200 main.FALSE if the cli responded with an error or given
3201 incorrect input
3202 """
3203 try:
3204 if not isinstance( appName, types.StringType ):
3205 main.log.error( self.name + ".activateApp(): appName must be" +
3206 " a string" )
3207 return main.FALSE
3208 status = self.appStatus( appName )
3209 if status == "INSTALLED":
3210 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003211 if check and response == main.TRUE:
3212 for i in range(10): # try 10 times then give up
3213 # TODO: Check with Thomas about this delay
3214 status = self.appStatus( appName )
3215 if status == "ACTIVE":
3216 return main.TRUE
3217 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003218 main.log.debug( "The state of application " +
3219 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003220 time.sleep( 1 )
3221 return main.FALSE
3222 else: # not 'check' or command didn't succeed
3223 return response
Jon Hall146f1522015-03-24 15:33:24 -07003224 elif status == "ACTIVE":
3225 return main.TRUE
3226 elif status == "UNINSTALLED":
3227 main.log.error( self.name + ": Tried to activate the " +
3228 "application '" + appName + "' which is not " +
3229 "installed." )
3230 else:
3231 main.log.error( "Unexpected return value from appStatus: " +
3232 str( status ) )
3233 return main.ERROR
3234 except TypeError:
3235 main.log.exception( self.name + ": Object not as expected" )
3236 return main.ERROR
3237 except pexpect.EOF:
3238 main.log.error( self.name + ": EOF exception found" )
3239 main.log.error( self.name + ": " + self.handle.before )
3240 main.cleanup()
3241 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003242 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003243 main.log.exception( self.name + ": Uncaught exception!" )
3244 main.cleanup()
3245 main.exit()
3246
Jon Hallbd16b922015-03-26 17:53:15 -07003247 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003248 """
3249 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003250 appName is the hierarchical app name, not the feature name
3251 If check is True, method will check the status of the app after the
3252 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003253 Returns main.TRUE if the command was successfully sent
3254 main.FALSE if the cli responded with an error or given
3255 incorrect input
3256 """
3257 try:
3258 if not isinstance( appName, types.StringType ):
3259 main.log.error( self.name + ".deactivateApp(): appName must " +
3260 "be a string" )
3261 return main.FALSE
3262 status = self.appStatus( appName )
3263 if status == "INSTALLED":
3264 return main.TRUE
3265 elif status == "ACTIVE":
3266 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003267 if check and response == main.TRUE:
3268 for i in range(10): # try 10 times then give up
3269 status = self.appStatus( appName )
3270 if status == "INSTALLED":
3271 return main.TRUE
3272 else:
3273 time.sleep( 1 )
3274 return main.FALSE
3275 else: # not check or command didn't succeed
3276 return response
Jon Hall146f1522015-03-24 15:33:24 -07003277 elif status == "UNINSTALLED":
3278 main.log.warn( self.name + ": Tried to deactivate the " +
3279 "application '" + appName + "' which is not " +
3280 "installed." )
3281 return main.TRUE
3282 else:
3283 main.log.error( "Unexpected return value from appStatus: " +
3284 str( status ) )
3285 return main.ERROR
3286 except TypeError:
3287 main.log.exception( self.name + ": Object not as expected" )
3288 return main.ERROR
3289 except pexpect.EOF:
3290 main.log.error( self.name + ": EOF exception found" )
3291 main.log.error( self.name + ": " + self.handle.before )
3292 main.cleanup()
3293 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003294 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003295 main.log.exception( self.name + ": Uncaught exception!" )
3296 main.cleanup()
3297 main.exit()
3298
Jon Hallbd16b922015-03-26 17:53:15 -07003299 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003300 """
3301 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003302 appName is the hierarchical app name, not the feature name
3303 If check is True, method will check the status of the app after the
3304 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003305 Returns main.TRUE if the command was successfully sent
3306 main.FALSE if the cli responded with an error or given
3307 incorrect input
3308 """
3309 # TODO: check with Thomas about the state machine for apps
3310 try:
3311 if not isinstance( appName, types.StringType ):
3312 main.log.error( self.name + ".uninstallApp(): appName must " +
3313 "be a string" )
3314 return main.FALSE
3315 status = self.appStatus( appName )
3316 if status == "INSTALLED":
3317 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003318 if check and response == main.TRUE:
3319 for i in range(10): # try 10 times then give up
3320 status = self.appStatus( appName )
3321 if status == "UNINSTALLED":
3322 return main.TRUE
3323 else:
3324 time.sleep( 1 )
3325 return main.FALSE
3326 else: # not check or command didn't succeed
3327 return response
Jon Hall146f1522015-03-24 15:33:24 -07003328 elif status == "ACTIVE":
3329 main.log.warn( self.name + ": Tried to uninstall the " +
3330 "application '" + appName + "' which is " +
3331 "currently active." )
3332 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003333 if check and response == main.TRUE:
3334 for i in range(10): # try 10 times then give up
3335 status = self.appStatus( appName )
3336 if status == "UNINSTALLED":
3337 return main.TRUE
3338 else:
3339 time.sleep( 1 )
3340 return main.FALSE
3341 else: # not check or command didn't succeed
3342 return response
Jon Hall146f1522015-03-24 15:33:24 -07003343 elif status == "UNINSTALLED":
3344 return main.TRUE
3345 else:
3346 main.log.error( "Unexpected return value from appStatus: " +
3347 str( status ) )
3348 return main.ERROR
3349 except TypeError:
3350 main.log.exception( self.name + ": Object not as expected" )
3351 return main.ERROR
3352 except pexpect.EOF:
3353 main.log.error( self.name + ": EOF exception found" )
3354 main.log.error( self.name + ": " + self.handle.before )
3355 main.cleanup()
3356 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003357 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003358 main.log.exception( self.name + ": Uncaught exception!" )
3359 main.cleanup()
3360 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003361
3362 def appIDs( self, jsonFormat=True ):
3363 """
3364 Show the mappings between app id and app names given by the 'app-ids'
3365 cli command
3366 """
3367 try:
3368 cmdStr = "app-ids"
3369 if jsonFormat:
3370 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003371 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003372 assert "Command not found:" not in output, output
3373 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003374 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003375 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003376 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003377 return None
3378 except TypeError:
3379 main.log.exception( self.name + ": Object not as expected" )
3380 return None
3381 except pexpect.EOF:
3382 main.log.error( self.name + ": EOF exception found" )
3383 main.log.error( self.name + ": " + self.handle.before )
3384 main.cleanup()
3385 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003386 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003387 main.log.exception( self.name + ": Uncaught exception!" )
3388 main.cleanup()
3389 main.exit()
3390
3391 def appToIDCheck( self ):
3392 """
3393 This method will check that each application's ID listed in 'apps' is
3394 the same as the ID listed in 'app-ids'. The check will also check that
3395 there are no duplicate IDs issued. Note that an app ID should be
3396 a globaly unique numerical identifier for app/app-like features. Once
3397 an ID is registered, the ID is never freed up so that if an app is
3398 reinstalled it will have the same ID.
3399
3400 Returns: main.TRUE if the check passes and
3401 main.FALSE if the check fails or
3402 main.ERROR if there is some error in processing the test
3403 """
3404 try:
Jon Hall390696c2015-05-05 17:13:41 -07003405 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003406 rawJson = self.appIDs( jsonFormat=True )
3407 if rawJson:
3408 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003409 else:
Jon Hallc6793552016-01-19 14:18:37 -08003410 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003411 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003412 rawJson = self.apps( jsonFormat=True )
3413 if rawJson:
3414 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003415 else:
Jon Hallc6793552016-01-19 14:18:37 -08003416 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003417 bail = True
3418 if bail:
3419 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003420 result = main.TRUE
3421 for app in apps:
3422 appID = app.get( 'id' )
3423 if appID is None:
3424 main.log.error( "Error parsing app: " + str( app ) )
3425 result = main.FALSE
3426 appName = app.get( 'name' )
3427 if appName is None:
3428 main.log.error( "Error parsing app: " + str( app ) )
3429 result = main.FALSE
3430 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003431 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003432 # main.log.debug( "Comparing " + str( app ) + " to " +
3433 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003434 if not current: # if ids doesn't have this id
3435 result = main.FALSE
3436 main.log.error( "'app-ids' does not have the ID for " +
3437 str( appName ) + " that apps does." )
3438 elif len( current ) > 1:
3439 # there is more than one app with this ID
3440 result = main.FALSE
3441 # We will log this later in the method
3442 elif not current[0][ 'name' ] == appName:
3443 currentName = current[0][ 'name' ]
3444 result = main.FALSE
3445 main.log.error( "'app-ids' has " + str( currentName ) +
3446 " registered under id:" + str( appID ) +
3447 " but 'apps' has " + str( appName ) )
3448 else:
3449 pass # id and name match!
3450 # now make sure that app-ids has no duplicates
3451 idsList = []
3452 namesList = []
3453 for item in ids:
3454 idsList.append( item[ 'id' ] )
3455 namesList.append( item[ 'name' ] )
3456 if len( idsList ) != len( set( idsList ) ) or\
3457 len( namesList ) != len( set( namesList ) ):
3458 main.log.error( "'app-ids' has some duplicate entries: \n"
3459 + json.dumps( ids,
3460 sort_keys=True,
3461 indent=4,
3462 separators=( ',', ': ' ) ) )
3463 result = main.FALSE
3464 return result
Jon Hallc6793552016-01-19 14:18:37 -08003465 except ( TypeError, ValueError ):
3466 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003467 return main.ERROR
3468 except pexpect.EOF:
3469 main.log.error( self.name + ": EOF exception found" )
3470 main.log.error( self.name + ": " + self.handle.before )
3471 main.cleanup()
3472 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003473 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003474 main.log.exception( self.name + ": Uncaught exception!" )
3475 main.cleanup()
3476 main.exit()
3477
Jon Hallfb760a02015-04-13 15:35:03 -07003478 def getCfg( self, component=None, propName=None, short=False,
3479 jsonFormat=True ):
3480 """
3481 Get configuration settings from onos cli
3482 Optional arguments:
3483 component - Optionally only list configurations for a specific
3484 component. If None, all components with configurations
3485 are displayed. Case Sensitive string.
3486 propName - If component is specified, propName option will show
3487 only this specific configuration from that component.
3488 Case Sensitive string.
3489 jsonFormat - Returns output as json. Note that this will override
3490 the short option
3491 short - Short, less verbose, version of configurations.
3492 This is overridden by the json option
3493 returns:
3494 Output from cli as a string or None on error
3495 """
3496 try:
3497 baseStr = "cfg"
3498 cmdStr = " get"
3499 componentStr = ""
3500 if component:
3501 componentStr += " " + component
3502 if propName:
3503 componentStr += " " + propName
3504 if jsonFormat:
3505 baseStr += " -j"
3506 elif short:
3507 baseStr += " -s"
3508 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003509 assert "Command not found:" not in output, output
3510 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003511 return output
3512 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003513 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003514 return None
3515 except TypeError:
3516 main.log.exception( self.name + ": Object not as expected" )
3517 return None
3518 except pexpect.EOF:
3519 main.log.error( self.name + ": EOF exception found" )
3520 main.log.error( self.name + ": " + self.handle.before )
3521 main.cleanup()
3522 main.exit()
3523 except Exception:
3524 main.log.exception( self.name + ": Uncaught exception!" )
3525 main.cleanup()
3526 main.exit()
3527
3528 def setCfg( self, component, propName, value=None, check=True ):
3529 """
3530 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003531 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003532 component - The case sensitive name of the component whose
3533 property is to be set
3534 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003535 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003536 value - The value to set the property to. If None, will unset the
3537 property and revert it to it's default value(if applicable)
3538 check - Boolean, Check whether the option was successfully set this
3539 only applies when a value is given.
3540 returns:
3541 main.TRUE on success or main.FALSE on failure. If check is False,
3542 will return main.TRUE unless there is an error
3543 """
3544 try:
3545 baseStr = "cfg"
3546 cmdStr = " set " + str( component ) + " " + str( propName )
3547 if value is not None:
3548 cmdStr += " " + str( value )
3549 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003550 assert "Command not found:" not in output, output
3551 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003552 if value and check:
3553 results = self.getCfg( component=str( component ),
3554 propName=str( propName ),
3555 jsonFormat=True )
3556 # Check if current value is what we just set
3557 try:
3558 jsonOutput = json.loads( results )
3559 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003560 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003561 main.log.exception( "Error parsing cfg output" )
3562 main.log.error( "output:" + repr( results ) )
3563 return main.FALSE
3564 if current == str( value ):
3565 return main.TRUE
3566 return main.FALSE
3567 return main.TRUE
3568 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003569 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003570 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003571 except ( TypeError, ValueError ):
3572 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003573 return main.FALSE
3574 except pexpect.EOF:
3575 main.log.error( self.name + ": EOF exception found" )
3576 main.log.error( self.name + ": " + self.handle.before )
3577 main.cleanup()
3578 main.exit()
3579 except Exception:
3580 main.log.exception( self.name + ": Uncaught exception!" )
3581 main.cleanup()
3582 main.exit()
3583
Jon Hall390696c2015-05-05 17:13:41 -07003584 def setTestAdd( self, setName, values ):
3585 """
3586 CLI command to add elements to a distributed set.
3587 Arguments:
3588 setName - The name of the set to add to.
3589 values - The value(s) to add to the set, space seperated.
3590 Example usages:
3591 setTestAdd( "set1", "a b c" )
3592 setTestAdd( "set2", "1" )
3593 returns:
3594 main.TRUE on success OR
3595 main.FALSE if elements were already in the set OR
3596 main.ERROR on error
3597 """
3598 try:
3599 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3600 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003601 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003602 try:
3603 # TODO: Maybe make this less hardcoded
3604 # ConsistentMap Exceptions
3605 assert "org.onosproject.store.service" not in output
3606 # Node not leader
3607 assert "java.lang.IllegalStateException" not in output
3608 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003609 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003610 "command: " + str( output ) )
3611 retryTime = 30 # Conservative time, given by Madan
3612 main.log.info( "Waiting " + str( retryTime ) +
3613 "seconds before retrying." )
3614 time.sleep( retryTime ) # Due to change in mastership
3615 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003616 assert "Error executing command" not in output
3617 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3618 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3619 main.log.info( self.name + ": " + output )
3620 if re.search( positiveMatch, output):
3621 return main.TRUE
3622 elif re.search( negativeMatch, output):
3623 return main.FALSE
3624 else:
3625 main.log.error( self.name + ": setTestAdd did not" +
3626 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003627 main.log.debug( self.name + " actual: " + repr( output ) )
3628 return main.ERROR
3629 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003630 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003631 return main.ERROR
3632 except TypeError:
3633 main.log.exception( self.name + ": Object not as expected" )
3634 return main.ERROR
3635 except pexpect.EOF:
3636 main.log.error( self.name + ": EOF exception found" )
3637 main.log.error( self.name + ": " + self.handle.before )
3638 main.cleanup()
3639 main.exit()
3640 except Exception:
3641 main.log.exception( self.name + ": Uncaught exception!" )
3642 main.cleanup()
3643 main.exit()
3644
3645 def setTestRemove( self, setName, values, clear=False, retain=False ):
3646 """
3647 CLI command to remove elements from a distributed set.
3648 Required arguments:
3649 setName - The name of the set to remove from.
3650 values - The value(s) to remove from the set, space seperated.
3651 Optional arguments:
3652 clear - Clear all elements from the set
3653 retain - Retain only the given values. (intersection of the
3654 original set and the given set)
3655 returns:
3656 main.TRUE on success OR
3657 main.FALSE if the set was not changed OR
3658 main.ERROR on error
3659 """
3660 try:
3661 cmdStr = "set-test-remove "
3662 if clear:
3663 cmdStr += "-c " + str( setName )
3664 elif retain:
3665 cmdStr += "-r " + str( setName ) + " " + str( values )
3666 else:
3667 cmdStr += str( setName ) + " " + str( values )
3668 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003669 try:
3670 # TODO: Maybe make this less hardcoded
3671 # ConsistentMap Exceptions
3672 assert "org.onosproject.store.service" not in output
3673 # Node not leader
3674 assert "java.lang.IllegalStateException" not in output
3675 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003676 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003677 "command: " + str( output ) )
3678 retryTime = 30 # Conservative time, given by Madan
3679 main.log.info( "Waiting " + str( retryTime ) +
3680 "seconds before retrying." )
3681 time.sleep( retryTime ) # Due to change in mastership
3682 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003683 assert "Command not found:" not in output, output
3684 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003685 main.log.info( self.name + ": " + output )
3686 if clear:
3687 pattern = "Set " + str( setName ) + " cleared"
3688 if re.search( pattern, output ):
3689 return main.TRUE
3690 elif retain:
3691 positivePattern = str( setName ) + " was pruned to contain " +\
3692 "only elements of set \[(.*)\]"
3693 negativePattern = str( setName ) + " was not changed by " +\
3694 "retaining only elements of the set " +\
3695 "\[(.*)\]"
3696 if re.search( positivePattern, output ):
3697 return main.TRUE
3698 elif re.search( negativePattern, output ):
3699 return main.FALSE
3700 else:
3701 positivePattern = "\[(.*)\] was removed from the set " +\
3702 str( setName )
3703 if ( len( values.split() ) == 1 ):
3704 negativePattern = "\[(.*)\] was not in set " +\
3705 str( setName )
3706 else:
3707 negativePattern = "No element of \[(.*)\] was in set " +\
3708 str( setName )
3709 if re.search( positivePattern, output ):
3710 return main.TRUE
3711 elif re.search( negativePattern, output ):
3712 return main.FALSE
3713 main.log.error( self.name + ": setTestRemove did not" +
3714 " match expected output" )
3715 main.log.debug( self.name + " expected: " + pattern )
3716 main.log.debug( self.name + " actual: " + repr( output ) )
3717 return main.ERROR
3718 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003719 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003720 return main.ERROR
3721 except TypeError:
3722 main.log.exception( self.name + ": Object not as expected" )
3723 return main.ERROR
3724 except pexpect.EOF:
3725 main.log.error( self.name + ": EOF exception found" )
3726 main.log.error( self.name + ": " + self.handle.before )
3727 main.cleanup()
3728 main.exit()
3729 except Exception:
3730 main.log.exception( self.name + ": Uncaught exception!" )
3731 main.cleanup()
3732 main.exit()
3733
3734 def setTestGet( self, setName, values="" ):
3735 """
3736 CLI command to get the elements in a distributed set.
3737 Required arguments:
3738 setName - The name of the set to remove from.
3739 Optional arguments:
3740 values - The value(s) to check if in the set, space seperated.
3741 returns:
3742 main.ERROR on error OR
3743 A list of elements in the set if no optional arguments are
3744 supplied OR
3745 A tuple containing the list then:
3746 main.FALSE if the given values are not in the set OR
3747 main.TRUE if the given values are in the set OR
3748 """
3749 try:
3750 values = str( values ).strip()
3751 setName = str( setName ).strip()
3752 length = len( values.split() )
3753 containsCheck = None
3754 # Patterns to match
3755 setPattern = "\[(.*)\]"
3756 pattern = "Items in set " + setName + ":\n" + setPattern
3757 containsTrue = "Set " + setName + " contains the value " + values
3758 containsFalse = "Set " + setName + " did not contain the value " +\
3759 values
3760 containsAllTrue = "Set " + setName + " contains the the subset " +\
3761 setPattern
3762 containsAllFalse = "Set " + setName + " did not contain the the" +\
3763 " subset " + setPattern
3764
3765 cmdStr = "set-test-get "
3766 cmdStr += setName + " " + values
3767 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003768 try:
3769 # TODO: Maybe make this less hardcoded
3770 # ConsistentMap Exceptions
3771 assert "org.onosproject.store.service" not in output
3772 # Node not leader
3773 assert "java.lang.IllegalStateException" not in output
3774 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003775 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003776 "command: " + str( output ) )
3777 retryTime = 30 # Conservative time, given by Madan
3778 main.log.info( "Waiting " + str( retryTime ) +
3779 "seconds before retrying." )
3780 time.sleep( retryTime ) # Due to change in mastership
3781 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003782 assert "Command not found:" not in output, output
3783 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003784 main.log.info( self.name + ": " + output )
3785
3786 if length == 0:
3787 match = re.search( pattern, output )
3788 else: # if given values
3789 if length == 1: # Contains output
3790 patternTrue = pattern + "\n" + containsTrue
3791 patternFalse = pattern + "\n" + containsFalse
3792 else: # ContainsAll output
3793 patternTrue = pattern + "\n" + containsAllTrue
3794 patternFalse = pattern + "\n" + containsAllFalse
3795 matchTrue = re.search( patternTrue, output )
3796 matchFalse = re.search( patternFalse, output )
3797 if matchTrue:
3798 containsCheck = main.TRUE
3799 match = matchTrue
3800 elif matchFalse:
3801 containsCheck = main.FALSE
3802 match = matchFalse
3803 else:
3804 main.log.error( self.name + " setTestGet did not match " +\
3805 "expected output" )
3806 main.log.debug( self.name + " expected: " + pattern )
3807 main.log.debug( self.name + " actual: " + repr( output ) )
3808 match = None
3809 if match:
3810 setMatch = match.group( 1 )
3811 if setMatch == '':
3812 setList = []
3813 else:
3814 setList = setMatch.split( ", " )
3815 if length > 0:
3816 return ( setList, containsCheck )
3817 else:
3818 return setList
3819 else: # no match
3820 main.log.error( self.name + ": setTestGet did not" +
3821 " match expected output" )
3822 main.log.debug( self.name + " expected: " + pattern )
3823 main.log.debug( self.name + " actual: " + repr( output ) )
3824 return main.ERROR
3825 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003826 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003827 return main.ERROR
3828 except TypeError:
3829 main.log.exception( self.name + ": Object not as expected" )
3830 return main.ERROR
3831 except pexpect.EOF:
3832 main.log.error( self.name + ": EOF exception found" )
3833 main.log.error( self.name + ": " + self.handle.before )
3834 main.cleanup()
3835 main.exit()
3836 except Exception:
3837 main.log.exception( self.name + ": Uncaught exception!" )
3838 main.cleanup()
3839 main.exit()
3840
3841 def setTestSize( self, setName ):
3842 """
3843 CLI command to get the elements in a distributed set.
3844 Required arguments:
3845 setName - The name of the set to remove from.
3846 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003847 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003848 None on error
3849 """
3850 try:
3851 # TODO: Should this check against the number of elements returned
3852 # and then return true/false based on that?
3853 setName = str( setName ).strip()
3854 # Patterns to match
3855 setPattern = "\[(.*)\]"
3856 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3857 setPattern
3858 cmdStr = "set-test-get -s "
3859 cmdStr += setName
3860 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003861 try:
3862 # TODO: Maybe make this less hardcoded
3863 # ConsistentMap Exceptions
3864 assert "org.onosproject.store.service" not in output
3865 # Node not leader
3866 assert "java.lang.IllegalStateException" not in output
3867 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003868 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003869 "command: " + str( output ) )
3870 retryTime = 30 # Conservative time, given by Madan
3871 main.log.info( "Waiting " + str( retryTime ) +
3872 "seconds before retrying." )
3873 time.sleep( retryTime ) # Due to change in mastership
3874 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003875 assert "Command not found:" not in output, output
3876 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003877 main.log.info( self.name + ": " + output )
3878 match = re.search( pattern, output )
3879 if match:
3880 setSize = int( match.group( 1 ) )
3881 setMatch = match.group( 2 )
3882 if len( setMatch.split() ) == setSize:
3883 main.log.info( "The size returned by " + self.name +
3884 " matches the number of elements in " +
3885 "the returned set" )
3886 else:
3887 main.log.error( "The size returned by " + self.name +
3888 " does not match the number of " +
3889 "elements in the returned set." )
3890 return setSize
3891 else: # no match
3892 main.log.error( self.name + ": setTestGet did not" +
3893 " match expected output" )
3894 main.log.debug( self.name + " expected: " + pattern )
3895 main.log.debug( self.name + " actual: " + repr( output ) )
3896 return None
3897 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003898 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003899 return None
Jon Hall390696c2015-05-05 17:13:41 -07003900 except TypeError:
3901 main.log.exception( self.name + ": Object not as expected" )
3902 return None
3903 except pexpect.EOF:
3904 main.log.error( self.name + ": EOF exception found" )
3905 main.log.error( self.name + ": " + self.handle.before )
3906 main.cleanup()
3907 main.exit()
3908 except Exception:
3909 main.log.exception( self.name + ": Uncaught exception!" )
3910 main.cleanup()
3911 main.exit()
3912
Jon Hall80daded2015-05-27 16:07:00 -07003913 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003914 """
3915 Command to list the various counters in the system.
3916 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003917 if jsonFormat, a string of the json object returned by the cli
3918 command
3919 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003920 None on error
3921 """
Jon Hall390696c2015-05-05 17:13:41 -07003922 try:
3923 counters = {}
3924 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003925 if jsonFormat:
3926 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003927 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003928 assert "Command not found:" not in output, output
3929 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003930 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003931 return output
Jon Hall390696c2015-05-05 17:13:41 -07003932 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003933 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003934 return None
Jon Hall390696c2015-05-05 17:13:41 -07003935 except TypeError:
3936 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003937 return None
Jon Hall390696c2015-05-05 17:13:41 -07003938 except pexpect.EOF:
3939 main.log.error( self.name + ": EOF exception found" )
3940 main.log.error( self.name + ": " + self.handle.before )
3941 main.cleanup()
3942 main.exit()
3943 except Exception:
3944 main.log.exception( self.name + ": Uncaught exception!" )
3945 main.cleanup()
3946 main.exit()
3947
Jon Halle1a3b752015-07-22 13:02:46 -07003948 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003949 """
Jon Halle1a3b752015-07-22 13:02:46 -07003950 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003951 Required arguments:
3952 counter - The name of the counter to increment.
3953 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003954 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003955 inMemory - use in memory map for the counter
3956 returns:
3957 integer value of the counter or
3958 None on Error
3959 """
3960 try:
3961 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003962 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003963 cmdStr = "counter-test-increment "
3964 if inMemory:
3965 cmdStr += "-i "
3966 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003967 if delta != 1:
3968 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003969 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003970 try:
3971 # TODO: Maybe make this less hardcoded
3972 # ConsistentMap Exceptions
3973 assert "org.onosproject.store.service" not in output
3974 # Node not leader
3975 assert "java.lang.IllegalStateException" not in output
3976 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003977 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003978 "command: " + str( output ) )
3979 retryTime = 30 # Conservative time, given by Madan
3980 main.log.info( "Waiting " + str( retryTime ) +
3981 "seconds before retrying." )
3982 time.sleep( retryTime ) # Due to change in mastership
3983 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003984 assert "Command not found:" not in output, output
3985 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003986 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003987 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003988 match = re.search( pattern, output )
3989 if match:
3990 return int( match.group( 1 ) )
3991 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003992 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003993 " match expected output." )
3994 main.log.debug( self.name + " expected: " + pattern )
3995 main.log.debug( self.name + " actual: " + repr( output ) )
3996 return None
3997 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003998 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003999 return None
4000 except TypeError:
4001 main.log.exception( self.name + ": Object not as expected" )
4002 return None
4003 except pexpect.EOF:
4004 main.log.error( self.name + ": EOF exception found" )
4005 main.log.error( self.name + ": " + self.handle.before )
4006 main.cleanup()
4007 main.exit()
4008 except Exception:
4009 main.log.exception( self.name + ": Uncaught exception!" )
4010 main.cleanup()
4011 main.exit()
4012
Jon Halle1a3b752015-07-22 13:02:46 -07004013 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4014 """
4015 CLI command to get a distributed counter then add a delta to it.
4016 Required arguments:
4017 counter - The name of the counter to increment.
4018 Optional arguments:
4019 delta - The long to add to the counter
4020 inMemory - use in memory map for the counter
4021 returns:
4022 integer value of the counter or
4023 None on Error
4024 """
4025 try:
4026 counter = str( counter )
4027 delta = int( delta )
4028 cmdStr = "counter-test-increment -g "
4029 if inMemory:
4030 cmdStr += "-i "
4031 cmdStr += counter
4032 if delta != 1:
4033 cmdStr += " " + str( delta )
4034 output = self.sendline( cmdStr )
4035 try:
4036 # TODO: Maybe make this less hardcoded
4037 # ConsistentMap Exceptions
4038 assert "org.onosproject.store.service" not in output
4039 # Node not leader
4040 assert "java.lang.IllegalStateException" not in output
4041 except AssertionError:
4042 main.log.error( "Error in processing '" + cmdStr + "' " +
4043 "command: " + str( output ) )
4044 retryTime = 30 # Conservative time, given by Madan
4045 main.log.info( "Waiting " + str( retryTime ) +
4046 "seconds before retrying." )
4047 time.sleep( retryTime ) # Due to change in mastership
4048 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004049 assert "Command not found:" not in output, output
4050 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004051 main.log.info( self.name + ": " + output )
4052 pattern = counter + " was updated to (-?\d+)"
4053 match = re.search( pattern, output )
4054 if match:
4055 return int( match.group( 1 ) )
4056 else:
4057 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4058 " match expected output." )
4059 main.log.debug( self.name + " expected: " + pattern )
4060 main.log.debug( self.name + " actual: " + repr( output ) )
4061 return None
4062 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004063 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004064 return None
4065 except TypeError:
4066 main.log.exception( self.name + ": Object not as expected" )
4067 return None
4068 except pexpect.EOF:
4069 main.log.error( self.name + ": EOF exception found" )
4070 main.log.error( self.name + ": " + self.handle.before )
4071 main.cleanup()
4072 main.exit()
4073 except Exception:
4074 main.log.exception( self.name + ": Uncaught exception!" )
4075 main.cleanup()
4076 main.exit()
4077
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004078 def summary( self, jsonFormat=True ):
4079 """
4080 Description: Execute summary command in onos
4081 Returns: json object ( summary -j ), returns main.FALSE if there is
4082 no output
4083
4084 """
4085 try:
4086 cmdStr = "summary"
4087 if jsonFormat:
4088 cmdStr += " -j"
4089 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004090 assert "Command not found:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004091 if re.search( "Error:", handle ):
4092 main.log.error( self.name + ": summary() response: " +
4093 str( handle ) )
4094 if not handle:
4095 main.log.error( self.name + ": There is no output in " +
4096 "summary command" )
4097 return main.FALSE
4098 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004099 except AssertionError:
4100 main.log.exception( "" )
4101 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004102 except TypeError:
4103 main.log.exception( self.name + ": Object not as expected" )
4104 return None
4105 except pexpect.EOF:
4106 main.log.error( self.name + ": EOF exception found" )
4107 main.log.error( self.name + ": " + self.handle.before )
4108 main.cleanup()
4109 main.exit()
4110 except Exception:
4111 main.log.exception( self.name + ": Uncaught exception!" )
4112 main.cleanup()
4113 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004114
4115 def transactionalMapGet( self, keyName, inMemory=False ):
4116 """
4117 CLI command to get the value of a key in a consistent map using
4118 transactions. This a test function and can only get keys from the
4119 test map hard coded into the cli command
4120 Required arguments:
4121 keyName - The name of the key to get
4122 Optional arguments:
4123 inMemory - use in memory map for the counter
4124 returns:
4125 The string value of the key or
4126 None on Error
4127 """
4128 try:
4129 keyName = str( keyName )
4130 cmdStr = "transactional-map-test-get "
4131 if inMemory:
4132 cmdStr += "-i "
4133 cmdStr += keyName
4134 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004135 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004136 try:
4137 # TODO: Maybe make this less hardcoded
4138 # ConsistentMap Exceptions
4139 assert "org.onosproject.store.service" not in output
4140 # Node not leader
4141 assert "java.lang.IllegalStateException" not in output
4142 except AssertionError:
4143 main.log.error( "Error in processing '" + cmdStr + "' " +
4144 "command: " + str( output ) )
4145 return None
4146 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4147 if "Key " + keyName + " not found." in output:
4148 return None
4149 else:
4150 match = re.search( pattern, output )
4151 if match:
4152 return match.groupdict()[ 'value' ]
4153 else:
4154 main.log.error( self.name + ": transactionlMapGet did not" +
4155 " match expected output." )
4156 main.log.debug( self.name + " expected: " + pattern )
4157 main.log.debug( self.name + " actual: " + repr( output ) )
4158 return None
Jon Hallc6793552016-01-19 14:18:37 -08004159 except AssertionError:
4160 main.log.exception( "" )
4161 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004162 except TypeError:
4163 main.log.exception( self.name + ": Object not as expected" )
4164 return None
4165 except pexpect.EOF:
4166 main.log.error( self.name + ": EOF exception found" )
4167 main.log.error( self.name + ": " + self.handle.before )
4168 main.cleanup()
4169 main.exit()
4170 except Exception:
4171 main.log.exception( self.name + ": Uncaught exception!" )
4172 main.cleanup()
4173 main.exit()
4174
4175 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4176 """
4177 CLI command to put a value into 'numKeys' number of keys in a
4178 consistent map using transactions. This a test function and can only
4179 put into keys named 'Key#' of the test map hard coded into the cli command
4180 Required arguments:
4181 numKeys - Number of keys to add the value to
4182 value - The string value to put into the keys
4183 Optional arguments:
4184 inMemory - use in memory map for the counter
4185 returns:
4186 A dictionary whose keys are the name of the keys put into the map
4187 and the values of the keys are dictionaries whose key-values are
4188 'value': value put into map and optionaly
4189 'oldValue': Previous value in the key or
4190 None on Error
4191
4192 Example output
4193 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4194 'Key2': {'value': 'Testing'} }
4195 """
4196 try:
4197 numKeys = str( numKeys )
4198 value = str( value )
4199 cmdStr = "transactional-map-test-put "
4200 if inMemory:
4201 cmdStr += "-i "
4202 cmdStr += numKeys + " " + value
4203 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004204 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004205 try:
4206 # TODO: Maybe make this less hardcoded
4207 # ConsistentMap Exceptions
4208 assert "org.onosproject.store.service" not in output
4209 # Node not leader
4210 assert "java.lang.IllegalStateException" not in output
4211 except AssertionError:
4212 main.log.error( "Error in processing '" + cmdStr + "' " +
4213 "command: " + str( output ) )
4214 return None
4215 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4216 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4217 results = {}
4218 for line in output.splitlines():
4219 new = re.search( newPattern, line )
4220 updated = re.search( updatedPattern, line )
4221 if new:
4222 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4223 elif updated:
4224 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004225 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004226 else:
4227 main.log.error( self.name + ": transactionlMapGet did not" +
4228 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004229 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4230 newPattern,
4231 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004232 main.log.debug( self.name + " actual: " + repr( output ) )
4233 return results
Jon Hallc6793552016-01-19 14:18:37 -08004234 except AssertionError:
4235 main.log.exception( "" )
4236 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004237 except TypeError:
4238 main.log.exception( self.name + ": Object not as expected" )
4239 return None
4240 except pexpect.EOF:
4241 main.log.error( self.name + ": EOF exception found" )
4242 main.log.error( self.name + ": " + self.handle.before )
4243 main.cleanup()
4244 main.exit()
4245 except Exception:
4246 main.log.exception( self.name + ": Uncaught exception!" )
4247 main.cleanup()
4248 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004249
acsmarsdaea66c2015-09-03 11:44:06 -07004250 def maps( self, jsonFormat=True ):
4251 """
4252 Description: Returns result of onos:maps
4253 Optional:
4254 * jsonFormat: enable json formatting of output
4255 """
4256 try:
4257 cmdStr = "maps"
4258 if jsonFormat:
4259 cmdStr += " -j"
4260 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004261 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004262 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004263 except AssertionError:
4264 main.log.exception( "" )
4265 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004266 except TypeError:
4267 main.log.exception( self.name + ": Object not as expected" )
4268 return None
4269 except pexpect.EOF:
4270 main.log.error( self.name + ": EOF exception found" )
4271 main.log.error( self.name + ": " + self.handle.before )
4272 main.cleanup()
4273 main.exit()
4274 except Exception:
4275 main.log.exception( self.name + ": Uncaught exception!" )
4276 main.cleanup()
4277 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004278
4279 def getSwController( self, uri, jsonFormat=True ):
4280 """
4281 Descrition: Gets the controller information from the device
4282 """
4283 try:
4284 cmd = "device-controllers "
4285 if jsonFormat:
4286 cmd += "-j "
4287 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004288 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004289 return response
Jon Hallc6793552016-01-19 14:18:37 -08004290 except AssertionError:
4291 main.log.exception( "" )
4292 return None
GlennRC050596c2015-11-18 17:06:41 -08004293 except TypeError:
4294 main.log.exception( self.name + ": Object not as expected" )
4295 return None
4296 except pexpect.EOF:
4297 main.log.error( self.name + ": EOF exception found" )
4298 main.log.error( self.name + ": " + self.handle.before )
4299 main.cleanup()
4300 main.exit()
4301 except Exception:
4302 main.log.exception( self.name + ": Uncaught exception!" )
4303 main.cleanup()
4304 main.exit()
4305
4306 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4307 """
4308 Descrition: sets the controller(s) for the specified device
4309
4310 Parameters:
4311 Required: uri - String: The uri of the device(switch).
4312 ip - String or List: The ip address of the controller.
4313 This parameter can be formed in a couple of different ways.
4314 VALID:
4315 10.0.0.1 - just the ip address
4316 tcp:10.0.0.1 - the protocol and the ip address
4317 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4318 so that you can add controllers with different
4319 protocols and ports
4320 INVALID:
4321 10.0.0.1:6653 - this is not supported by ONOS
4322
4323 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4324 port - The port number.
4325 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4326
4327 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4328 """
4329 try:
4330 cmd = "device-setcontrollers"
4331
4332 if jsonFormat:
4333 cmd += " -j"
4334 cmd += " " + uri
4335 if isinstance( ip, str ):
4336 ip = [ip]
4337 for item in ip:
4338 if ":" in item:
4339 sitem = item.split( ":" )
4340 if len(sitem) == 3:
4341 cmd += " " + item
4342 elif "." in sitem[1]:
4343 cmd += " {}:{}".format(item, port)
4344 else:
4345 main.log.error( "Malformed entry: " + item )
4346 raise TypeError
4347 else:
4348 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004349 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004350 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004351 if "Error" in response:
4352 main.log.error( response )
4353 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004354 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004355 except AssertionError:
4356 main.log.exception( "" )
4357 return None
GlennRC050596c2015-11-18 17:06:41 -08004358 except TypeError:
4359 main.log.exception( self.name + ": Object not as expected" )
4360 return main.FALSE
4361 except pexpect.EOF:
4362 main.log.error( self.name + ": EOF exception found" )
4363 main.log.error( self.name + ": " + self.handle.before )
4364 main.cleanup()
4365 main.exit()
4366 except Exception:
4367 main.log.exception( self.name + ": Uncaught exception!" )
4368 main.cleanup()
4369 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004370
4371 def removeDevice( self, device ):
4372 '''
4373 Description:
4374 Remove a device from ONOS by passing the uri of the device(s).
4375 Parameters:
4376 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4377 Returns:
4378 Returns main.FALSE if an exception is thrown or an error is present
4379 in the response. Otherwise, returns main.TRUE.
4380 NOTE:
4381 If a host cannot be removed, then this function will return main.FALSE
4382 '''
4383 try:
4384 if type( device ) is str:
4385 device = list( device )
4386
4387 for d in device:
4388 time.sleep( 1 )
4389 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004390 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004391 if "Error" in response:
4392 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4393 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004394 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004395 except AssertionError:
4396 main.log.exception( "" )
4397 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004398 except TypeError:
4399 main.log.exception( self.name + ": Object not as expected" )
4400 return main.FALSE
4401 except pexpect.EOF:
4402 main.log.error( self.name + ": EOF exception found" )
4403 main.log.error( self.name + ": " + self.handle.before )
4404 main.cleanup()
4405 main.exit()
4406 except Exception:
4407 main.log.exception( self.name + ": Uncaught exception!" )
4408 main.cleanup()
4409 main.exit()
4410
4411 def removeHost( self, host ):
4412 '''
4413 Description:
4414 Remove a host from ONOS by passing the id of the host(s)
4415 Parameters:
4416 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4417 Returns:
4418 Returns main.FALSE if an exception is thrown or an error is present
4419 in the response. Otherwise, returns main.TRUE.
4420 NOTE:
4421 If a host cannot be removed, then this function will return main.FALSE
4422 '''
4423 try:
4424 if type( host ) is str:
4425 host = list( host )
4426
4427 for h in host:
4428 time.sleep( 1 )
4429 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004430 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004431 if "Error" in response:
4432 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4433 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004434 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004435 except AssertionError:
4436 main.log.exception( "" )
4437 return None
GlennRC20fc6522015-12-23 23:26:57 -08004438 except TypeError:
4439 main.log.exception( self.name + ": Object not as expected" )
4440 return main.FALSE
4441 except pexpect.EOF:
4442 main.log.error( self.name + ": EOF exception found" )
4443 main.log.error( self.name + ": " + self.handle.before )
4444 main.cleanup()
4445 main.exit()
4446 except Exception:
4447 main.log.exception( self.name + ": Uncaught exception!" )
4448 main.cleanup()
4449 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004450
Jon Hallc6793552016-01-19 14:18:37 -08004451 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004452 '''
4453 Description:
4454 Bring link down or up in the null-provider.
4455 params:
4456 begin - (string) One end of a device or switch.
4457 end - (string) the other end of the device or switch
4458 returns:
4459 main.TRUE if no exceptions were thrown and no Errors are
4460 present in the resoponse. Otherwise, returns main.FALSE
4461 '''
4462 try:
Jon Hallc6793552016-01-19 14:18:37 -08004463 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004464 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004465 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004466 if "Error" in response or "Failure" in response:
4467 main.log.error( response )
4468 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004469 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004470 except AssertionError:
4471 main.log.exception( "" )
4472 return None
GlennRCed771242016-01-13 17:02:47 -08004473 except TypeError:
4474 main.log.exception( self.name + ": Object not as expected" )
4475 return main.FALSE
4476 except pexpect.EOF:
4477 main.log.error( self.name + ": EOF exception found" )
4478 main.log.error( self.name + ": " + self.handle.before )
4479 main.cleanup()
4480 main.exit()
4481 except Exception:
4482 main.log.exception( self.name + ": Uncaught exception!" )
4483 main.cleanup()
4484 main.exit()
4485