blob: 93f98b85661a35e10e58afc0e508874fd26a6e14 [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
Jeremy42df2e72016-02-23 16:37:46 -08001747 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1748 """
1749 Description:
1750 Remove all the intents
1751 Optional args:-
1752 -s or --sync: Waits for the removal before returning
1753 -p or --purge: Purge the intent from the store after removal
1754 Returns:
1755 Returns main.TRUE if all intents are removed, otherwise returns
1756 main.FALSE; Returns None for exception
1757 """
1758 try:
1759 cmdStr = "remove-intent"
1760 if purge:
1761 cmdStr += " -p"
1762 if sync:
1763 cmdStr += " -s"
1764
1765 cmdStr += " " + app
1766 handle = self.sendline( cmdStr )
1767 assert "Command not found:" not in handle, handle
1768 if re.search( "Error", handle ):
1769 main.log.error( "Error in removing intent" )
1770 return main.FALSE
1771 else:
1772 return main.TRUE
1773 except AssertionError:
1774 main.log.exception( "" )
1775 return None
1776 except TypeError:
1777 main.log.exception( self.name + ": Object not as expected" )
1778 return None
1779 except pexpect.EOF:
1780 main.log.error( self.name + ": EOF exception found" )
1781 main.log.error( self.name + ": " + self.handle.before )
1782 main.cleanup()
1783 main.exit()
1784 except Exception:
1785 main.log.exception( self.name + ": Uncaught exception!" )
1786 main.cleanup()
1787 main.exit()
1788
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001789 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001790 """
1791 Purges all WITHDRAWN Intents
1792 """
1793 try:
1794 cmdStr = "purge-intents"
1795 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001796 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001797 if re.search( "Error", handle ):
1798 main.log.error( "Error in purging intents" )
1799 return main.FALSE
1800 else:
1801 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001802 except AssertionError:
1803 main.log.exception( "" )
1804 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001805 except TypeError:
1806 main.log.exception( self.name + ": Object not as expected" )
1807 return None
1808 except pexpect.EOF:
1809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
1811 main.cleanup()
1812 main.exit()
1813 except Exception:
1814 main.log.exception( self.name + ": Uncaught exception!" )
1815 main.cleanup()
1816 main.exit()
1817
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001819 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001820 NOTE: This method should be used after installing application:
1821 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001822 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001823 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001824 Description:
1825 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001826 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001827 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001828 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001829 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001830 cmdStr += " -j"
1831 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001832 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001833 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001834 except AssertionError:
1835 main.log.exception( "" )
1836 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001837 except TypeError:
1838 main.log.exception( self.name + ": Object not as expected" )
1839 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001840 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001841 main.log.error( self.name + ": EOF exception found" )
1842 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001843 main.cleanup()
1844 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001845 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001846 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001847 main.cleanup()
1848 main.exit()
1849
pingping-lin54b03372015-08-13 14:43:10 -07001850 def ipv4RouteNumber( self ):
1851 """
1852 NOTE: This method should be used after installing application:
1853 onos-app-sdnip
1854 Description:
1855 Obtain the total IPv4 routes number in the system
1856 """
1857 try:
1858 cmdStr = "routes -s -j"
1859 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001860 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001861 jsonResult = json.loads( handle )
1862 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001863 except AssertionError:
1864 main.log.exception( "" )
1865 return None
1866 except ( TypeError, ValueError ):
1867 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001868 return None
1869 except pexpect.EOF:
1870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
1872 main.cleanup()
1873 main.exit()
1874 except Exception:
1875 main.log.exception( self.name + ": Uncaught exception!" )
1876 main.cleanup()
1877 main.exit()
1878
pingping-lin8244a3b2015-09-16 13:36:56 -07001879 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001880 """
andrewonlabe6745342014-10-17 14:29:13 -04001881 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001882 Obtain intents from the ONOS cli.
1883 Optional:
1884 * jsonFormat: Enable output formatting in json, default to True
1885 * summary: Whether only output the intent summary, defaults to False
1886 * type: Only output a certain type of intent. This options is valid
1887 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001888 """
andrewonlabe6745342014-10-17 14:29:13 -04001889 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001890 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001891 if summary:
1892 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001893 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001894 cmdStr += " -j"
1895 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001896 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001897 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001898 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001899 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001900 else:
Jon Hallff566d52016-01-15 14:45:36 -08001901 intentType = ""
1902 # IF we want the summary of a specific intent type
1903 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001904 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001905 if intentType in jsonResult.keys():
1906 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001907 else:
Jon Hallff566d52016-01-15 14:45:36 -08001908 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001909 return handle
1910 else:
1911 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001912 except AssertionError:
1913 main.log.exception( "" )
1914 return None
1915 except ( TypeError, ValueError ):
1916 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001917 return None
1918 except pexpect.EOF:
1919 main.log.error( self.name + ": EOF exception found" )
1920 main.log.error( self.name + ": " + self.handle.before )
1921 main.cleanup()
1922 main.exit()
1923 except Exception:
1924 main.log.exception( self.name + ": Uncaught exception!" )
1925 main.cleanup()
1926 main.exit()
1927
kelvin-onlab54400a92015-02-26 18:05:51 -08001928 def getIntentState(self, intentsId, intentsJson=None):
1929 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001930 Check intent state.
1931 Accepts a single intent ID (string type) or a list of intent IDs.
1932 Returns the state(string type) of the id if a single intent ID is
1933 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001934 Returns a dictionary with intent IDs as the key and its
1935 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001936 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001937 intentId: intent ID (string type)
1938 intentsJson: parsed json object from the onos:intents api
1939 Returns:
1940 state = An intent's state- INSTALL,WITHDRAWN etc.
1941 stateDict = Dictionary of intent's state. intent ID as the keys and
1942 state as the values.
1943 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001944 try:
1945 state = "State is Undefined"
1946 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001947 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001948 else:
Jon Hallc6793552016-01-19 14:18:37 -08001949 rawJson = intentsJson
1950 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001951 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001952 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001953 if intentsId == intent[ 'id' ]:
1954 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001955 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001956 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1957 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001958 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001959 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001960 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001961 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001962 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001963 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001964 if intentsId[ i ] == intents[ 'id' ]:
1965 stateDict[ 'state' ] = intents[ 'state' ]
1966 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001967 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001968 break
Jon Hallefbd9792015-03-05 16:11:36 -08001969 if len( intentsId ) != len( dictList ):
1970 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001971 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001972 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001973 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001974 return None
Jon Hallc6793552016-01-19 14:18:37 -08001975 except ( TypeError, ValueError ):
1976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001977 return None
1978 except pexpect.EOF:
1979 main.log.error( self.name + ": EOF exception found" )
1980 main.log.error( self.name + ": " + self.handle.before )
1981 main.cleanup()
1982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001983 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001984 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001985 main.cleanup()
1986 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001987
kelvin-onlabf512e942015-06-08 19:42:59 -07001988 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001989 """
1990 Description:
1991 Check intents state
1992 Required:
1993 intentsId - List of intents ID to be checked
1994 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001995 expectedState - Check the expected state(s) of each intents
1996 state in the list.
1997 *NOTE: You can pass in a list of expected state,
1998 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001999 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002000 Returns main.TRUE only if all intent are the same as expected states
2001 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002002 """
2003 try:
2004 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002005 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002006 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002007 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002008 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002009 "getting intents state" )
2010 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002011
2012 if isinstance( expectedState, types.StringType ):
2013 for intents in intentsDict:
2014 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002015 main.log.debug( self.name + " : Intent ID - " +
2016 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002017 " actual state = " +
2018 intents.get( 'state' )
2019 + " does not equal expected state = "
2020 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002021 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002022
2023 elif isinstance( expectedState, types.ListType ):
2024 for intents in intentsDict:
2025 if not any( state == intents.get( 'state' ) for state in
2026 expectedState ):
2027 main.log.debug( self.name + " : Intent ID - " +
2028 intents.get( 'id' ) +
2029 " actual state = " +
2030 intents.get( 'state' ) +
2031 " does not equal expected states = "
2032 + str( expectedState ) )
2033 returnValue = main.FALSE
2034
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002035 if returnValue == main.TRUE:
2036 main.log.info( self.name + ": All " +
2037 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002038 " intents are in " + str( expectedState ) +
2039 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002040 return returnValue
2041 except TypeError:
2042 main.log.exception( self.name + ": Object not as expected" )
2043 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()
andrewonlabe6745342014-10-17 14:29:13 -04002053
GlennRCed771242016-01-13 17:02:47 -08002054 def checkIntentSummary( self, timeout=60 ):
2055 """
2056 Description:
2057 Check the number of installed intents.
2058 Optional:
2059 timeout - the timeout for pexcept
2060 Return:
2061 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2062 , otherwise, returns main.FALSE.
2063 """
2064
2065 try:
2066 cmd = "intents -s -j"
2067
2068 # Check response if something wrong
2069 response = self.sendline( cmd, timeout=timeout )
2070 if response == None:
2071 return main.False
2072 response = json.loads( response )
2073
2074 # get total and installed number, see if they are match
2075 allState = response.get( 'all' )
2076 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002077 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002078 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002079 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002080 return main.FALSE
2081
Jon Hallc6793552016-01-19 14:18:37 -08002082 except ( TypeError, ValueError ):
2083 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002084 return None
2085 except pexpect.EOF:
2086 main.log.error( self.name + ": EOF exception found" )
2087 main.log.error( self.name + ": " + self.handle.before )
2088 main.cleanup()
2089 main.exit()
2090 except Exception:
2091 main.log.exception( self.name + ": Uncaught exception!" )
2092 main.cleanup()
2093 main.exit()
2094
2095 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002096 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002097 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002098 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002099 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002100 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002101 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002102 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002103 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002105 cmdStr += " -j "
2106 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002107 handle = self.sendline( cmdStr, timeout=timeout )
2108 assert "Command not found:" not in handle, handle
2109 if re.search( "Error:", handle ):
2110 main.log.error( self.name + ": flows() response: " +
2111 str( handle ) )
2112 return handle
2113 except AssertionError:
2114 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002115 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return None
Jon Hallc6793552016-01-19 14:18:37 -08002119 except pexpect.TIMEOUT:
2120 main.log.error( self.name + ": ONOS timeout" )
2121 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002122 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002123 main.log.error( self.name + ": EOF exception found" )
2124 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002125 main.cleanup()
2126 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002127 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002128 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002129 main.cleanup()
2130 main.exit()
2131
GlennRCed771242016-01-13 17:02:47 -08002132
Jon Hallc6793552016-01-19 14:18:37 -08002133 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002134 """
2135 Description:
GlennRCed771242016-01-13 17:02:47 -08002136 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002137 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2138 if the count of those states is 0, which means all current flows
2139 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002140 Optional:
GlennRCed771242016-01-13 17:02:47 -08002141 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002142 Return:
2143 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002144 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002145 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002146 """
2147 try:
GlennRCed771242016-01-13 17:02:47 -08002148 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2149 checkedStates = []
2150 statesCount = [0, 0, 0, 0]
2151 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002152 rawFlows = self.flows( state=s, timeout = timeout )
2153 checkedStates.append( json.loads( rawFlows ) )
2154 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002155 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002156 try:
2157 statesCount[i] += int( c.get( "flowCount" ) )
2158 except TypeError:
2159 main.log.exception( "Json object not as expected" )
2160 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002161
GlennRCed771242016-01-13 17:02:47 -08002162 # We want to count PENDING_ADD if isPENDING is true
2163 if isPENDING:
2164 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2165 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002166 else:
GlennRCed771242016-01-13 17:02:47 -08002167 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2168 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002169 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002170 except ( TypeError, ValueError ):
2171 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002172 return None
2173 except pexpect.EOF:
2174 main.log.error( self.name + ": EOF exception found" )
2175 main.log.error( self.name + ": " + self.handle.before )
2176 main.cleanup()
2177 main.exit()
2178 except Exception:
2179 main.log.exception( self.name + ": Uncaught exception!" )
2180 main.cleanup()
2181 main.exit()
2182
GlennRCed771242016-01-13 17:02:47 -08002183 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2184 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002185 """
andrewonlab87852b02014-11-19 18:44:19 -05002186 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002187 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002188 a specific point-to-point intent definition
2189 Required:
GlennRCed771242016-01-13 17:02:47 -08002190 * ingress: specify source dpid
2191 * egress: specify destination dpid
2192 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002193 Optional:
GlennRCed771242016-01-13 17:02:47 -08002194 * offset: the keyOffset is where the next batch of intents
2195 will be installed
2196 Returns: If failed to push test intents, it will returen None,
2197 if successful, return true.
2198 Timeout expection will return None,
2199 TypeError will return false
2200 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002201 """
andrewonlab87852b02014-11-19 18:44:19 -05002202 try:
GlennRCed771242016-01-13 17:02:47 -08002203 if background:
2204 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002205 else:
GlennRCed771242016-01-13 17:02:47 -08002206 back = ""
2207 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002208 ingress,
2209 egress,
2210 batchSize,
2211 offset,
2212 back )
GlennRCed771242016-01-13 17:02:47 -08002213 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002214 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002215 main.log.info( response )
2216 if response == None:
2217 return None
2218
2219 # TODO: We should handle if there is failure in installation
2220 return main.TRUE
2221
Jon Hallc6793552016-01-19 14:18:37 -08002222 except AssertionError:
2223 main.log.exception( "" )
2224 return None
GlennRCed771242016-01-13 17:02:47 -08002225 except pexpect.TIMEOUT:
2226 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002227 return None
andrewonlab87852b02014-11-19 18:44:19 -05002228 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002229 main.log.error( self.name + ": EOF exception found" )
2230 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002231 main.cleanup()
2232 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002233 except TypeError:
2234 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002235 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002236 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002237 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002238 main.cleanup()
2239 main.exit()
2240
YPZhangf6f14a02016-01-28 15:17:31 -08002241 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002242 """
2243 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002244 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002245 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002246 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002247 """
YPZhange3109a72016-02-02 11:25:37 -08002248
YPZhangb5d3f832016-01-23 22:54:26 -08002249 try:
YPZhange3109a72016-02-02 11:25:37 -08002250 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002251 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002252 totalFlows = self.sendline( cmd, timeout=timeout )
2253
2254 if totalFlows == None:
2255 # if timeout, we will get total number of all flows, and subtract other states
2256 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2257 checkedStates = []
2258 totalFlows = 0
2259 statesCount = [0, 0, 0, 0]
2260
2261 # get total flows from summary
2262 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2263 totalFlows = int( response.get("flows") )
2264
2265 for s in states:
2266 rawFlows = self.flows( state=s, timeout = timeout )
2267 if rawFlows == None:
2268 # if timeout, return the total flows number from summary command
2269 return totalFlows
2270 checkedStates.append( json.loads( rawFlows ) )
2271
2272 # Calculate ADDED flows number, equal total subtracts others
2273 for i in range( len( states ) ):
2274 for c in checkedStates[i]:
2275 try:
2276 statesCount[i] += int( c.get( "flowCount" ) )
2277 except TypeError:
2278 main.log.exception( "Json object not as expected" )
2279 totalFlows = totalFlows - int( statesCount[i] )
2280 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2281
2282 return totalFlows
2283
2284 return totalFlows
2285
YPZhangb5d3f832016-01-23 22:54:26 -08002286 except TypeError:
2287 main.log.exception( self.name + ": Object not as expected" )
2288 return None
2289 except pexpect.EOF:
2290 main.log.error( self.name + ": EOF exception found" )
2291 main.log.error( self.name + ": " + self.handle.before )
2292 main.cleanup()
2293 main.exit()
2294 except Exception:
2295 main.log.exception( self.name + ": Uncaught exception!" )
2296 main.cleanup()
2297 main.exit()
2298
2299 def getTotalIntentsNum( self ):
2300 """
2301 Description:
2302 Get the total number of intents, include every states.
2303 Return:
2304 The number of intents
2305 """
2306 try:
2307 cmd = "summary -j"
2308 response = self.sendline( cmd )
2309 if response == None:
2310 return -1
2311 response = json.loads( response )
2312 return int( response.get("intents") )
2313 except TypeError:
2314 main.log.exception( self.name + ": Object not as expected" )
2315 return None
2316 except pexpect.EOF:
2317 main.log.error( self.name + ": EOF exception found" )
2318 main.log.error( self.name + ": " + self.handle.before )
2319 main.cleanup()
2320 main.exit()
2321 except Exception:
2322 main.log.exception( self.name + ": Uncaught exception!" )
2323 main.cleanup()
2324 main.exit()
2325
kelvin-onlabd3b64892015-01-20 13:26:24 -08002326 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002327 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002328 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002329 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002330 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002331 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002332 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002333 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002334 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002335 cmdStr += " -j"
2336 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002337 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002338 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002339 except AssertionError:
2340 main.log.exception( "" )
2341 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002348 main.cleanup()
2349 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002350 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002351 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002352 main.cleanup()
2353 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002354
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002356 """
2357 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002358 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002359 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002360 """
andrewonlab867212a2014-10-22 20:13:38 -04002361 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002362 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002363 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002364 cmdStr += " -j"
2365 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002366 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002367 if handle:
2368 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002369 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002370 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002371 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002372 else:
2373 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002374 except AssertionError:
2375 main.log.exception( "" )
2376 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002377 except TypeError:
2378 main.log.exception( self.name + ": Object not as expected" )
2379 return None
andrewonlab867212a2014-10-22 20:13:38 -04002380 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002381 main.log.error( self.name + ": EOF exception found" )
2382 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002383 main.cleanup()
2384 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002385 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002386 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002387 main.cleanup()
2388 main.exit()
2389
kelvin8ec71442015-01-15 16:57:00 -08002390 # Wrapper functions ****************
2391 # Wrapper functions use existing driver
2392 # functions and extends their use case.
2393 # For example, we may use the output of
2394 # a normal driver function, and parse it
2395 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002396
kelvin-onlabd3b64892015-01-20 13:26:24 -08002397 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002398 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002399 Description:
2400 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002401 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002402 try:
kelvin8ec71442015-01-15 16:57:00 -08002403 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002404 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002405 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002406
kelvin8ec71442015-01-15 16:57:00 -08002407 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002408 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2409 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002410 match = re.search('id=0x([\da-f]+),', intents)
2411 if match:
2412 tmpId = match.group()[3:-1]
2413 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002414 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002415
Jon Halld4d4b372015-01-28 16:02:41 -08002416 except TypeError:
2417 main.log.exception( self.name + ": Object not as expected" )
2418 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002419 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002420 main.log.error( self.name + ": EOF exception found" )
2421 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002422 main.cleanup()
2423 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002424 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002425 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002426 main.cleanup()
2427 main.exit()
2428
Jon Hall30b82fa2015-03-04 17:15:43 -08002429 def FlowAddedCount( self, deviceId ):
2430 """
2431 Determine the number of flow rules for the given device id that are
2432 in the added state
2433 """
2434 try:
2435 cmdStr = "flows any " + str( deviceId ) + " | " +\
2436 "grep 'state=ADDED' | wc -l"
2437 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002438 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002439 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002440 except AssertionError:
2441 main.log.exception( "" )
2442 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002443 except pexpect.EOF:
2444 main.log.error( self.name + ": EOF exception found" )
2445 main.log.error( self.name + ": " + self.handle.before )
2446 main.cleanup()
2447 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002448 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002449 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002450 main.cleanup()
2451 main.exit()
2452
kelvin-onlabd3b64892015-01-20 13:26:24 -08002453 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002454 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002455 Use 'devices' function to obtain list of all devices
2456 and parse the result to obtain a list of all device
2457 id's. Returns this list. Returns empty list if no
2458 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002459 List is ordered sequentially
2460
andrewonlab3e15ead2014-10-15 14:21:34 -04002461 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002462 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002463 the ids. By obtaining the list of device ids on the fly,
2464 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002465 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002466 try:
kelvin8ec71442015-01-15 16:57:00 -08002467 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002468 devicesStr = self.devices( jsonFormat=False )
2469 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002470
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002472 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002473 return idList
kelvin8ec71442015-01-15 16:57:00 -08002474
2475 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002476 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002477 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002478 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002479 # Split list further into arguments before and after string
2480 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002481 # append to idList
2482 for arg in tempList:
2483 idList.append( arg.split( "id=" )[ 1 ] )
2484 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002485
Jon Halld4d4b372015-01-28 16:02:41 -08002486 except TypeError:
2487 main.log.exception( self.name + ": Object not as expected" )
2488 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002489 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002490 main.log.error( self.name + ": EOF exception found" )
2491 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002492 main.cleanup()
2493 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002494 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002495 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002496 main.cleanup()
2497 main.exit()
2498
kelvin-onlabd3b64892015-01-20 13:26:24 -08002499 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002500 """
andrewonlab7c211572014-10-15 16:45:20 -04002501 Uses 'nodes' function to obtain list of all nodes
2502 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002503 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002504 Returns:
2505 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002506 """
andrewonlab7c211572014-10-15 16:45:20 -04002507 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002508 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002509 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002510 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002511 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002512 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002513 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002514 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002515 nodesJson = json.loads( nodesStr )
2516 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002517 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002518 except ( TypeError, ValueError ):
2519 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002520 return None
andrewonlab7c211572014-10-15 16:45:20 -04002521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002522 main.log.error( self.name + ": EOF exception found" )
2523 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002524 main.cleanup()
2525 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002527 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002528 main.cleanup()
2529 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002530
kelvin-onlabd3b64892015-01-20 13:26:24 -08002531 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002532 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002533 Return the first device from the devices api whose 'id' contains 'dpid'
2534 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002535 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002536 try:
kelvin8ec71442015-01-15 16:57:00 -08002537 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002538 return None
2539 else:
kelvin8ec71442015-01-15 16:57:00 -08002540 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 rawDevices = self.devices()
2542 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002543 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002545 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2546 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002547 return device
2548 return None
Jon Hallc6793552016-01-19 14:18:37 -08002549 except ( TypeError, ValueError ):
2550 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002551 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002552 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002553 main.log.error( self.name + ": EOF exception found" )
2554 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002555 main.cleanup()
2556 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002557 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002558 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002559 main.cleanup()
2560 main.exit()
2561
kelvin-onlabd3b64892015-01-20 13:26:24 -08002562 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002563 """
Jon Hallefbd9792015-03-05 16:11:36 -08002564 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002565 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002566 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002567
Jon Hall42db6dc2014-10-24 19:03:48 -04002568 Params: ip = ip used for the onos cli
2569 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002570 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002571 logLevel = level to log to. Currently accepts
2572 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002573
2574
kelvin-onlabd3b64892015-01-20 13:26:24 -08002575 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002576
Jon Hallefbd9792015-03-05 16:11:36 -08002577 Returns: main.TRUE if the number of switches and links are correct,
2578 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002579 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002580 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002581 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002582 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002583 if topology == {}:
2584 return main.ERROR
2585 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002586 # Is the number of switches is what we expected
2587 devices = topology.get( 'devices', False )
2588 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002589 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002590 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002591 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002592 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002593 linkCheck = ( int( links ) == int( numolink ) )
2594 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002595 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002596 output += "The number of links and switches match " +\
2597 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002598 result = main.TRUE
2599 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002600 output += "The number of links and switches does not match " +\
2601 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002602 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 output = output + "\n ONOS sees %i devices (%i expected) \
2604 and %i links (%i expected)" % (
2605 int( devices ), int( numoswitch ), int( links ),
2606 int( numolink ) )
2607 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002608 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002609 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002610 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002611 else:
Jon Hall390696c2015-05-05 17:13:41 -07002612 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002613 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002614 except TypeError:
2615 main.log.exception( self.name + ": Object not as expected" )
2616 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002617 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002618 main.log.error( self.name + ": EOF exception found" )
2619 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002620 main.cleanup()
2621 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002622 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002623 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002624 main.cleanup()
2625 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002626
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002628 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002629 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002630 deviceId must be the id of a device as seen in the onos devices command
2631 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002632 role must be either master, standby, or none
2633
Jon Halle3f39ff2015-01-13 11:50:53 -08002634 Returns:
2635 main.TRUE or main.FALSE based on argument verification and
2636 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002637 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002638 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002639 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002640 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002641 cmdStr = "device-role " +\
2642 str( deviceId ) + " " +\
2643 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002644 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002645 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002646 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002647 if re.search( "Error", handle ):
2648 # end color output to escape any colours
2649 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002650 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002651 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002652 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002653 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002654 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002655 main.log.error( "Invalid 'role' given to device_role(). " +
2656 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002657 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002658 except AssertionError:
2659 main.log.exception( "" )
2660 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002661 except TypeError:
2662 main.log.exception( self.name + ": Object not as expected" )
2663 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002665 main.log.error( self.name + ": EOF exception found" )
2666 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002667 main.cleanup()
2668 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002669 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002670 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002671 main.cleanup()
2672 main.exit()
2673
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002675 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002676 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002677 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002678 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002679 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002680 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002681 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002683 cmdStr += " -j"
2684 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002685 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002686 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002687 except AssertionError:
2688 main.log.exception( "" )
2689 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002690 except TypeError:
2691 main.log.exception( self.name + ": Object not as expected" )
2692 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002693 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002694 main.log.error( self.name + ": EOF exception found" )
2695 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002696 main.cleanup()
2697 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002698 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002699 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002700 main.cleanup()
2701 main.exit()
2702
kelvin-onlabd3b64892015-01-20 13:26:24 -08002703 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002704 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002705 CLI command to get the current leader for the Election test application
2706 NOTE: Requires installation of the onos-app-election feature
2707 Returns: Node IP of the leader if one exists
2708 None if none exists
2709 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002710 """
Jon Hall94fd0472014-12-08 11:52:42 -08002711 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 cmdStr = "election-test-leader"
2713 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002714 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002715 # Leader
2716 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002717 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 nodeSearch = re.search( leaderPattern, response )
2719 if nodeSearch:
2720 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002721 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002722 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002723 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002724 # no leader
2725 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002726 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002727 nullSearch = re.search( nullPattern, response )
2728 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002729 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002730 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002731 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002732 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002733 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002734 if re.search( errorPattern, response ):
2735 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002736 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002737 return main.FALSE
2738 else:
Jon Hall390696c2015-05-05 17:13:41 -07002739 main.log.error( "Error in electionTestLeader on " + self.name +
2740 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002741 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002742 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002743 except AssertionError:
2744 main.log.exception( "" )
2745 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002746 except TypeError:
2747 main.log.exception( self.name + ": Object not as expected" )
2748 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002749 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002750 main.log.error( self.name + ": EOF exception found" )
2751 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002752 main.cleanup()
2753 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002754 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002755 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002756 main.cleanup()
2757 main.exit()
2758
kelvin-onlabd3b64892015-01-20 13:26:24 -08002759 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002760 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002761 CLI command to run for leadership of the Election test application.
2762 NOTE: Requires installation of the onos-app-election feature
2763 Returns: Main.TRUE on success
2764 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002765 """
Jon Hall94fd0472014-12-08 11:52:42 -08002766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002767 cmdStr = "election-test-run"
2768 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002769 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002770 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002771 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002772 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002773 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002774 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002775 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002776 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002777 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002778 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002779 errorPattern = "Command\snot\sfound"
2780 if re.search( errorPattern, response ):
2781 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002782 return main.FALSE
2783 else:
Jon Hall390696c2015-05-05 17:13:41 -07002784 main.log.error( "Error in electionTestRun on " + self.name +
2785 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002786 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002787 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002788 except AssertionError:
2789 main.log.exception( "" )
2790 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002791 except TypeError:
2792 main.log.exception( self.name + ": Object not as expected" )
2793 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002794 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002795 main.log.error( self.name + ": EOF exception found" )
2796 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002797 main.cleanup()
2798 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002799 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002800 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002801 main.cleanup()
2802 main.exit()
2803
kelvin-onlabd3b64892015-01-20 13:26:24 -08002804 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002805 """
Jon Hall94fd0472014-12-08 11:52:42 -08002806 * CLI command to withdraw the local node from leadership election for
2807 * the Election test application.
2808 #NOTE: Requires installation of the onos-app-election feature
2809 Returns: Main.TRUE on success
2810 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002811 """
Jon Hall94fd0472014-12-08 11:52:42 -08002812 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 cmdStr = "election-test-withdraw"
2814 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002815 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002816 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002817 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002818 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002819 if re.search( successPattern, response ):
2820 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002821 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002822 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002823 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002824 errorPattern = "Command\snot\sfound"
2825 if re.search( errorPattern, response ):
2826 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002827 return main.FALSE
2828 else:
Jon Hall390696c2015-05-05 17:13:41 -07002829 main.log.error( "Error in electionTestWithdraw on " +
2830 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002831 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002832 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002833 except AssertionError:
2834 main.log.exception( "" )
2835 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002836 except TypeError:
2837 main.log.exception( self.name + ": Object not as expected" )
2838 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002839 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002842 main.cleanup()
2843 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002844 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002845 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002846 main.cleanup()
2847 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002848
kelvin8ec71442015-01-15 16:57:00 -08002849 def getDevicePortsEnabledCount( self, dpid ):
2850 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002851 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002852 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002853 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002854 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2856 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002857 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002858 if re.search( "No such device", output ):
2859 main.log.error( "Error in getting ports" )
2860 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002861 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002862 return output
Jon Hallc6793552016-01-19 14:18:37 -08002863 except AssertionError:
2864 main.log.exception( "" )
2865 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002866 except TypeError:
2867 main.log.exception( self.name + ": Object not as expected" )
2868 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002869 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002870 main.log.error( self.name + ": EOF exception found" )
2871 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002872 main.cleanup()
2873 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002874 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002875 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002876 main.cleanup()
2877 main.exit()
2878
kelvin8ec71442015-01-15 16:57:00 -08002879 def getDeviceLinksActiveCount( self, dpid ):
2880 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002881 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002882 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002883 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002884 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2886 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002887 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002888 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002889 main.log.error( "Error in getting ports " )
2890 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002891 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002892 return output
Jon Hallc6793552016-01-19 14:18:37 -08002893 except AssertionError:
2894 main.log.exception( "" )
2895 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002902 main.cleanup()
2903 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002904 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002905 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002906 main.cleanup()
2907 main.exit()
2908
kelvin8ec71442015-01-15 16:57:00 -08002909 def getAllIntentIds( self ):
2910 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002911 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002912 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002913 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002914 cmdStr = "onos:intents | grep id="
2915 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002916 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002917 if re.search( "Error", output ):
2918 main.log.error( "Error in getting ports" )
2919 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002920 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002921 return output
Jon Hallc6793552016-01-19 14:18:37 -08002922 except AssertionError:
2923 main.log.exception( "" )
2924 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002925 except TypeError:
2926 main.log.exception( self.name + ": Object not as expected" )
2927 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002931 main.cleanup()
2932 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002934 main.log.exception( self.name + ": Uncaught exception!" )
2935 main.cleanup()
2936 main.exit()
2937
Jon Hall73509952015-02-24 16:42:56 -08002938 def intentSummary( self ):
2939 """
Jon Hallefbd9792015-03-05 16:11:36 -08002940 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002941 """
2942 try:
2943 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002944 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002945 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002946 states.append( intent.get( 'state', None ) )
2947 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002948 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002949 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002950 except ( TypeError, ValueError ):
2951 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002952 return None
2953 except pexpect.EOF:
2954 main.log.error( self.name + ": EOF exception found" )
2955 main.log.error( self.name + ": " + self.handle.before )
2956 main.cleanup()
2957 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002958 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002959 main.log.exception( self.name + ": Uncaught exception!" )
2960 main.cleanup()
2961 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002962
Jon Hall61282e32015-03-19 11:34:11 -07002963 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002964 """
2965 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002966 Optional argument:
2967 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002968 """
Jon Hall63604932015-02-26 17:09:50 -08002969 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002970 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002971 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002972 cmdStr += " -j"
2973 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002974 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002975 return output
Jon Hallc6793552016-01-19 14:18:37 -08002976 except AssertionError:
2977 main.log.exception( "" )
2978 return None
Jon Hall63604932015-02-26 17:09:50 -08002979 except TypeError:
2980 main.log.exception( self.name + ": Object not as expected" )
2981 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002982 except pexpect.EOF:
2983 main.log.error( self.name + ": EOF exception found" )
2984 main.log.error( self.name + ": " + self.handle.before )
2985 main.cleanup()
2986 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002987 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002988 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002989 main.cleanup()
2990 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002991
acsmarsa4a4d1e2015-07-10 16:01:24 -07002992 def leaderCandidates( self, jsonFormat=True ):
2993 """
2994 Returns the output of the leaders -c command.
2995 Optional argument:
2996 * jsonFormat - boolean indicating if you want output in json
2997 """
2998 try:
2999 cmdStr = "onos:leaders -c"
3000 if jsonFormat:
3001 cmdStr += " -j"
3002 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003003 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003004 return output
Jon Hallc6793552016-01-19 14:18:37 -08003005 except AssertionError:
3006 main.log.exception( "" )
3007 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003008 except TypeError:
3009 main.log.exception( self.name + ": Object not as expected" )
3010 return None
3011 except pexpect.EOF:
3012 main.log.error( self.name + ": EOF exception found" )
3013 main.log.error( self.name + ": " + self.handle.before )
3014 main.cleanup()
3015 main.exit()
3016 except Exception:
3017 main.log.exception( self.name + ": Uncaught exception!" )
3018 main.cleanup()
3019 main.exit()
3020
Jon Hallc6793552016-01-19 14:18:37 -08003021 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003022 """
3023 Returns a list in format [leader,candidate1,candidate2,...] for a given
3024 topic parameter and an empty list if the topic doesn't exist
3025 If no leader is elected leader in the returned list will be "none"
3026 Returns None if there is a type error processing the json object
3027 """
3028 try:
Jon Hall6e709752016-02-01 13:38:46 -08003029 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003030 rawOutput = self.sendline( cmdStr )
3031 assert "Command not found:" not in rawOutput, rawOutput
3032 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003033 results = []
3034 for dict in output:
3035 if dict["topic"] == topic:
3036 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003037 candidates = re.split( ", ", dict["candidates"][1:-1] )
3038 results.append( leader )
3039 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003040 return results
Jon Hallc6793552016-01-19 14:18:37 -08003041 except AssertionError:
3042 main.log.exception( "" )
3043 return None
3044 except ( TypeError, ValueError ):
3045 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003046 return None
3047 except pexpect.EOF:
3048 main.log.error( self.name + ": EOF exception found" )
3049 main.log.error( self.name + ": " + self.handle.before )
3050 main.cleanup()
3051 main.exit()
3052 except Exception:
3053 main.log.exception( self.name + ": Uncaught exception!" )
3054 main.cleanup()
3055 main.exit()
3056
Jon Hall61282e32015-03-19 11:34:11 -07003057 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003058 """
3059 Returns the output of the intent Pending map.
3060 """
Jon Hall63604932015-02-26 17:09:50 -08003061 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003062 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003063 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003064 cmdStr += " -j"
3065 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003066 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003067 return output
Jon Hallc6793552016-01-19 14:18:37 -08003068 except AssertionError:
3069 main.log.exception( "" )
3070 return None
Jon Hall63604932015-02-26 17:09:50 -08003071 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 Hall63604932015-02-26 17:09:50 -08003080 main.log.exception( self.name + ": Uncaught exception!" )
3081 main.cleanup()
3082 main.exit()
3083
Jon Hall61282e32015-03-19 11:34:11 -07003084 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003085 """
3086 Returns the output of the raft partitions command for ONOS.
3087 """
Jon Hall61282e32015-03-19 11:34:11 -07003088 # Sample JSON
3089 # {
3090 # "leader": "tcp://10.128.30.11:7238",
3091 # "members": [
3092 # "tcp://10.128.30.11:7238",
3093 # "tcp://10.128.30.17:7238",
3094 # "tcp://10.128.30.13:7238",
3095 # ],
3096 # "name": "p1",
3097 # "term": 3
3098 # },
Jon Hall63604932015-02-26 17:09:50 -08003099 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003100 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003101 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003102 cmdStr += " -j"
3103 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003104 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003105 return output
Jon Hallc6793552016-01-19 14:18:37 -08003106 except AssertionError:
3107 main.log.exception( "" )
3108 return None
Jon Hall63604932015-02-26 17:09:50 -08003109 except TypeError:
3110 main.log.exception( self.name + ": Object not as expected" )
3111 return None
3112 except pexpect.EOF:
3113 main.log.error( self.name + ": EOF exception found" )
3114 main.log.error( self.name + ": " + self.handle.before )
3115 main.cleanup()
3116 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003117 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003118 main.log.exception( self.name + ": Uncaught exception!" )
3119 main.cleanup()
3120 main.exit()
3121
Jon Hallbe379602015-03-24 13:39:32 -07003122 def apps( self, jsonFormat=True ):
3123 """
3124 Returns the output of the apps command for ONOS. This command lists
3125 information about installed ONOS applications
3126 """
3127 # Sample JSON object
3128 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3129 # "description":"ONOS OpenFlow protocol southbound providers",
3130 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3131 # "features":"[onos-openflow]","state":"ACTIVE"}]
3132 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003133 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003134 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003135 cmdStr += " -j"
3136 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003137 assert "Command not found:" not in output, output
3138 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003139 return output
Jon Hallbe379602015-03-24 13:39:32 -07003140 # FIXME: look at specific exceptions/Errors
3141 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003142 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003143 return None
3144 except TypeError:
3145 main.log.exception( self.name + ": Object not as expected" )
3146 return None
3147 except pexpect.EOF:
3148 main.log.error( self.name + ": EOF exception found" )
3149 main.log.error( self.name + ": " + self.handle.before )
3150 main.cleanup()
3151 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003152 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003153 main.log.exception( self.name + ": Uncaught exception!" )
3154 main.cleanup()
3155 main.exit()
3156
Jon Hall146f1522015-03-24 15:33:24 -07003157 def appStatus( self, appName ):
3158 """
3159 Uses the onos:apps cli command to return the status of an application.
3160 Returns:
3161 "ACTIVE" - If app is installed and activated
3162 "INSTALLED" - If app is installed and deactivated
3163 "UNINSTALLED" - If app is not installed
3164 None - on error
3165 """
Jon Hall146f1522015-03-24 15:33:24 -07003166 try:
3167 if not isinstance( appName, types.StringType ):
3168 main.log.error( self.name + ".appStatus(): appName must be" +
3169 " a string" )
3170 return None
3171 output = self.apps( jsonFormat=True )
3172 appsJson = json.loads( output )
3173 state = None
3174 for app in appsJson:
3175 if appName == app.get('name'):
3176 state = app.get('state')
3177 break
3178 if state == "ACTIVE" or state == "INSTALLED":
3179 return state
3180 elif state is None:
3181 return "UNINSTALLED"
3182 elif state:
3183 main.log.error( "Unexpected state from 'onos:apps': " +
3184 str( state ) )
3185 return state
Jon Hallc6793552016-01-19 14:18:37 -08003186 except ( TypeError, ValueError ):
3187 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3188 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003189 return None
3190 except pexpect.EOF:
3191 main.log.error( self.name + ": EOF exception found" )
3192 main.log.error( self.name + ": " + self.handle.before )
3193 main.cleanup()
3194 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003195 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003196 main.log.exception( self.name + ": Uncaught exception!" )
3197 main.cleanup()
3198 main.exit()
3199
Jon Hallbe379602015-03-24 13:39:32 -07003200 def app( self, appName, option ):
3201 """
3202 Interacts with the app command for ONOS. This command manages
3203 application inventory.
3204 """
Jon Hallbe379602015-03-24 13:39:32 -07003205 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003206 # Validate argument types
3207 valid = True
3208 if not isinstance( appName, types.StringType ):
3209 main.log.error( self.name + ".app(): appName must be a " +
3210 "string" )
3211 valid = False
3212 if not isinstance( option, types.StringType ):
3213 main.log.error( self.name + ".app(): option must be a string" )
3214 valid = False
3215 if not valid:
3216 return main.FALSE
3217 # Validate Option
3218 option = option.lower()
3219 # NOTE: Install may become a valid option
3220 if option == "activate":
3221 pass
3222 elif option == "deactivate":
3223 pass
3224 elif option == "uninstall":
3225 pass
3226 else:
3227 # Invalid option
3228 main.log.error( "The ONOS app command argument only takes " +
3229 "the values: (activate|deactivate|uninstall)" +
3230 "; was given '" + option + "'")
3231 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003232 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003233 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003234 if "Error executing command" in output:
3235 main.log.error( "Error in processing onos:app command: " +
3236 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003237 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003238 elif "No such application" in output:
3239 main.log.error( "The application '" + appName +
3240 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003241 return main.FALSE
3242 elif "Command not found:" in output:
3243 main.log.error( "Error in processing onos:app command: " +
3244 str( output ) )
3245 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003246 elif "Unsupported command:" in output:
3247 main.log.error( "Incorrect command given to 'app': " +
3248 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003249 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003250 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003251 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003252 return main.TRUE
3253 except TypeError:
3254 main.log.exception( self.name + ": Object not as expected" )
3255 return main.ERROR
3256 except pexpect.EOF:
3257 main.log.error( self.name + ": EOF exception found" )
3258 main.log.error( self.name + ": " + self.handle.before )
3259 main.cleanup()
3260 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003261 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003262 main.log.exception( self.name + ": Uncaught exception!" )
3263 main.cleanup()
3264 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003265
Jon Hallbd16b922015-03-26 17:53:15 -07003266 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003267 """
3268 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003269 appName is the hierarchical app name, not the feature name
3270 If check is True, method will check the status of the app after the
3271 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003272 Returns main.TRUE if the command was successfully sent
3273 main.FALSE if the cli responded with an error or given
3274 incorrect input
3275 """
3276 try:
3277 if not isinstance( appName, types.StringType ):
3278 main.log.error( self.name + ".activateApp(): appName must be" +
3279 " a string" )
3280 return main.FALSE
3281 status = self.appStatus( appName )
3282 if status == "INSTALLED":
3283 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003284 if check and response == main.TRUE:
3285 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003286 status = self.appStatus( appName )
3287 if status == "ACTIVE":
3288 return main.TRUE
3289 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003290 main.log.debug( "The state of application " +
3291 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003292 time.sleep( 1 )
3293 return main.FALSE
3294 else: # not 'check' or command didn't succeed
3295 return response
Jon Hall146f1522015-03-24 15:33:24 -07003296 elif status == "ACTIVE":
3297 return main.TRUE
3298 elif status == "UNINSTALLED":
3299 main.log.error( self.name + ": Tried to activate the " +
3300 "application '" + appName + "' which is not " +
3301 "installed." )
3302 else:
3303 main.log.error( "Unexpected return value from appStatus: " +
3304 str( status ) )
3305 return main.ERROR
3306 except TypeError:
3307 main.log.exception( self.name + ": Object not as expected" )
3308 return main.ERROR
3309 except pexpect.EOF:
3310 main.log.error( self.name + ": EOF exception found" )
3311 main.log.error( self.name + ": " + self.handle.before )
3312 main.cleanup()
3313 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003314 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003315 main.log.exception( self.name + ": Uncaught exception!" )
3316 main.cleanup()
3317 main.exit()
3318
Jon Hallbd16b922015-03-26 17:53:15 -07003319 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003320 """
3321 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003322 appName is the hierarchical app name, not the feature name
3323 If check is True, method will check the status of the app after the
3324 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003325 Returns main.TRUE if the command was successfully sent
3326 main.FALSE if the cli responded with an error or given
3327 incorrect input
3328 """
3329 try:
3330 if not isinstance( appName, types.StringType ):
3331 main.log.error( self.name + ".deactivateApp(): appName must " +
3332 "be a string" )
3333 return main.FALSE
3334 status = self.appStatus( appName )
3335 if status == "INSTALLED":
3336 return main.TRUE
3337 elif status == "ACTIVE":
3338 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003339 if check and response == main.TRUE:
3340 for i in range(10): # try 10 times then give up
3341 status = self.appStatus( appName )
3342 if status == "INSTALLED":
3343 return main.TRUE
3344 else:
3345 time.sleep( 1 )
3346 return main.FALSE
3347 else: # not check or command didn't succeed
3348 return response
Jon Hall146f1522015-03-24 15:33:24 -07003349 elif status == "UNINSTALLED":
3350 main.log.warn( self.name + ": Tried to deactivate the " +
3351 "application '" + appName + "' which is not " +
3352 "installed." )
3353 return main.TRUE
3354 else:
3355 main.log.error( "Unexpected return value from appStatus: " +
3356 str( status ) )
3357 return main.ERROR
3358 except TypeError:
3359 main.log.exception( self.name + ": Object not as expected" )
3360 return main.ERROR
3361 except pexpect.EOF:
3362 main.log.error( self.name + ": EOF exception found" )
3363 main.log.error( self.name + ": " + self.handle.before )
3364 main.cleanup()
3365 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003366 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003367 main.log.exception( self.name + ": Uncaught exception!" )
3368 main.cleanup()
3369 main.exit()
3370
Jon Hallbd16b922015-03-26 17:53:15 -07003371 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003372 """
3373 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003374 appName is the hierarchical app name, not the feature name
3375 If check is True, method will check the status of the app after the
3376 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003377 Returns main.TRUE if the command was successfully sent
3378 main.FALSE if the cli responded with an error or given
3379 incorrect input
3380 """
3381 # TODO: check with Thomas about the state machine for apps
3382 try:
3383 if not isinstance( appName, types.StringType ):
3384 main.log.error( self.name + ".uninstallApp(): appName must " +
3385 "be a string" )
3386 return main.FALSE
3387 status = self.appStatus( appName )
3388 if status == "INSTALLED":
3389 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003390 if check and response == main.TRUE:
3391 for i in range(10): # try 10 times then give up
3392 status = self.appStatus( appName )
3393 if status == "UNINSTALLED":
3394 return main.TRUE
3395 else:
3396 time.sleep( 1 )
3397 return main.FALSE
3398 else: # not check or command didn't succeed
3399 return response
Jon Hall146f1522015-03-24 15:33:24 -07003400 elif status == "ACTIVE":
3401 main.log.warn( self.name + ": Tried to uninstall the " +
3402 "application '" + appName + "' which is " +
3403 "currently active." )
3404 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003405 if check and response == main.TRUE:
3406 for i in range(10): # try 10 times then give up
3407 status = self.appStatus( appName )
3408 if status == "UNINSTALLED":
3409 return main.TRUE
3410 else:
3411 time.sleep( 1 )
3412 return main.FALSE
3413 else: # not check or command didn't succeed
3414 return response
Jon Hall146f1522015-03-24 15:33:24 -07003415 elif status == "UNINSTALLED":
3416 return main.TRUE
3417 else:
3418 main.log.error( "Unexpected return value from appStatus: " +
3419 str( status ) )
3420 return main.ERROR
3421 except TypeError:
3422 main.log.exception( self.name + ": Object not as expected" )
3423 return main.ERROR
3424 except pexpect.EOF:
3425 main.log.error( self.name + ": EOF exception found" )
3426 main.log.error( self.name + ": " + self.handle.before )
3427 main.cleanup()
3428 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003429 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003430 main.log.exception( self.name + ": Uncaught exception!" )
3431 main.cleanup()
3432 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003433
3434 def appIDs( self, jsonFormat=True ):
3435 """
3436 Show the mappings between app id and app names given by the 'app-ids'
3437 cli command
3438 """
3439 try:
3440 cmdStr = "app-ids"
3441 if jsonFormat:
3442 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003443 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003444 assert "Command not found:" not in output, output
3445 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003446 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003447 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003448 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003449 return None
3450 except TypeError:
3451 main.log.exception( self.name + ": Object not as expected" )
3452 return None
3453 except pexpect.EOF:
3454 main.log.error( self.name + ": EOF exception found" )
3455 main.log.error( self.name + ": " + self.handle.before )
3456 main.cleanup()
3457 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003458 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003459 main.log.exception( self.name + ": Uncaught exception!" )
3460 main.cleanup()
3461 main.exit()
3462
3463 def appToIDCheck( self ):
3464 """
3465 This method will check that each application's ID listed in 'apps' is
3466 the same as the ID listed in 'app-ids'. The check will also check that
3467 there are no duplicate IDs issued. Note that an app ID should be
3468 a globaly unique numerical identifier for app/app-like features. Once
3469 an ID is registered, the ID is never freed up so that if an app is
3470 reinstalled it will have the same ID.
3471
3472 Returns: main.TRUE if the check passes and
3473 main.FALSE if the check fails or
3474 main.ERROR if there is some error in processing the test
3475 """
3476 try:
Jon Hall390696c2015-05-05 17:13:41 -07003477 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003478 rawJson = self.appIDs( jsonFormat=True )
3479 if rawJson:
3480 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003481 else:
Jon Hallc6793552016-01-19 14:18:37 -08003482 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003483 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003484 rawJson = self.apps( jsonFormat=True )
3485 if rawJson:
3486 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003487 else:
Jon Hallc6793552016-01-19 14:18:37 -08003488 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003489 bail = True
3490 if bail:
3491 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003492 result = main.TRUE
3493 for app in apps:
3494 appID = app.get( 'id' )
3495 if appID is None:
3496 main.log.error( "Error parsing app: " + str( app ) )
3497 result = main.FALSE
3498 appName = app.get( 'name' )
3499 if appName is None:
3500 main.log.error( "Error parsing app: " + str( app ) )
3501 result = main.FALSE
3502 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003503 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003504 # main.log.debug( "Comparing " + str( app ) + " to " +
3505 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003506 if not current: # if ids doesn't have this id
3507 result = main.FALSE
3508 main.log.error( "'app-ids' does not have the ID for " +
3509 str( appName ) + " that apps does." )
3510 elif len( current ) > 1:
3511 # there is more than one app with this ID
3512 result = main.FALSE
3513 # We will log this later in the method
3514 elif not current[0][ 'name' ] == appName:
3515 currentName = current[0][ 'name' ]
3516 result = main.FALSE
3517 main.log.error( "'app-ids' has " + str( currentName ) +
3518 " registered under id:" + str( appID ) +
3519 " but 'apps' has " + str( appName ) )
3520 else:
3521 pass # id and name match!
3522 # now make sure that app-ids has no duplicates
3523 idsList = []
3524 namesList = []
3525 for item in ids:
3526 idsList.append( item[ 'id' ] )
3527 namesList.append( item[ 'name' ] )
3528 if len( idsList ) != len( set( idsList ) ) or\
3529 len( namesList ) != len( set( namesList ) ):
3530 main.log.error( "'app-ids' has some duplicate entries: \n"
3531 + json.dumps( ids,
3532 sort_keys=True,
3533 indent=4,
3534 separators=( ',', ': ' ) ) )
3535 result = main.FALSE
3536 return result
Jon Hallc6793552016-01-19 14:18:37 -08003537 except ( TypeError, ValueError ):
3538 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003539 return main.ERROR
3540 except pexpect.EOF:
3541 main.log.error( self.name + ": EOF exception found" )
3542 main.log.error( self.name + ": " + self.handle.before )
3543 main.cleanup()
3544 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003545 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003546 main.log.exception( self.name + ": Uncaught exception!" )
3547 main.cleanup()
3548 main.exit()
3549
Jon Hallfb760a02015-04-13 15:35:03 -07003550 def getCfg( self, component=None, propName=None, short=False,
3551 jsonFormat=True ):
3552 """
3553 Get configuration settings from onos cli
3554 Optional arguments:
3555 component - Optionally only list configurations for a specific
3556 component. If None, all components with configurations
3557 are displayed. Case Sensitive string.
3558 propName - If component is specified, propName option will show
3559 only this specific configuration from that component.
3560 Case Sensitive string.
3561 jsonFormat - Returns output as json. Note that this will override
3562 the short option
3563 short - Short, less verbose, version of configurations.
3564 This is overridden by the json option
3565 returns:
3566 Output from cli as a string or None on error
3567 """
3568 try:
3569 baseStr = "cfg"
3570 cmdStr = " get"
3571 componentStr = ""
3572 if component:
3573 componentStr += " " + component
3574 if propName:
3575 componentStr += " " + propName
3576 if jsonFormat:
3577 baseStr += " -j"
3578 elif short:
3579 baseStr += " -s"
3580 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003581 assert "Command not found:" not in output, output
3582 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003583 return output
3584 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003585 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003586 return None
3587 except TypeError:
3588 main.log.exception( self.name + ": Object not as expected" )
3589 return None
3590 except pexpect.EOF:
3591 main.log.error( self.name + ": EOF exception found" )
3592 main.log.error( self.name + ": " + self.handle.before )
3593 main.cleanup()
3594 main.exit()
3595 except Exception:
3596 main.log.exception( self.name + ": Uncaught exception!" )
3597 main.cleanup()
3598 main.exit()
3599
3600 def setCfg( self, component, propName, value=None, check=True ):
3601 """
3602 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003603 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003604 component - The case sensitive name of the component whose
3605 property is to be set
3606 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003607 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003608 value - The value to set the property to. If None, will unset the
3609 property and revert it to it's default value(if applicable)
3610 check - Boolean, Check whether the option was successfully set this
3611 only applies when a value is given.
3612 returns:
3613 main.TRUE on success or main.FALSE on failure. If check is False,
3614 will return main.TRUE unless there is an error
3615 """
3616 try:
3617 baseStr = "cfg"
3618 cmdStr = " set " + str( component ) + " " + str( propName )
3619 if value is not None:
3620 cmdStr += " " + str( value )
3621 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003622 assert "Command not found:" not in output, output
3623 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003624 if value and check:
3625 results = self.getCfg( component=str( component ),
3626 propName=str( propName ),
3627 jsonFormat=True )
3628 # Check if current value is what we just set
3629 try:
3630 jsonOutput = json.loads( results )
3631 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003632 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003633 main.log.exception( "Error parsing cfg output" )
3634 main.log.error( "output:" + repr( results ) )
3635 return main.FALSE
3636 if current == str( value ):
3637 return main.TRUE
3638 return main.FALSE
3639 return main.TRUE
3640 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003641 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003642 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003643 except ( TypeError, ValueError ):
3644 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003645 return main.FALSE
3646 except pexpect.EOF:
3647 main.log.error( self.name + ": EOF exception found" )
3648 main.log.error( self.name + ": " + self.handle.before )
3649 main.cleanup()
3650 main.exit()
3651 except Exception:
3652 main.log.exception( self.name + ": Uncaught exception!" )
3653 main.cleanup()
3654 main.exit()
3655
Jon Hall390696c2015-05-05 17:13:41 -07003656 def setTestAdd( self, setName, values ):
3657 """
3658 CLI command to add elements to a distributed set.
3659 Arguments:
3660 setName - The name of the set to add to.
3661 values - The value(s) to add to the set, space seperated.
3662 Example usages:
3663 setTestAdd( "set1", "a b c" )
3664 setTestAdd( "set2", "1" )
3665 returns:
3666 main.TRUE on success OR
3667 main.FALSE if elements were already in the set OR
3668 main.ERROR on error
3669 """
3670 try:
3671 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3672 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003673 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003674 try:
3675 # TODO: Maybe make this less hardcoded
3676 # ConsistentMap Exceptions
3677 assert "org.onosproject.store.service" not in output
3678 # Node not leader
3679 assert "java.lang.IllegalStateException" not in output
3680 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003681 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003682 "command: " + str( output ) )
3683 retryTime = 30 # Conservative time, given by Madan
3684 main.log.info( "Waiting " + str( retryTime ) +
3685 "seconds before retrying." )
3686 time.sleep( retryTime ) # Due to change in mastership
3687 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003688 assert "Error executing command" not in output
3689 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3690 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3691 main.log.info( self.name + ": " + output )
3692 if re.search( positiveMatch, output):
3693 return main.TRUE
3694 elif re.search( negativeMatch, output):
3695 return main.FALSE
3696 else:
3697 main.log.error( self.name + ": setTestAdd did not" +
3698 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003699 main.log.debug( self.name + " actual: " + repr( output ) )
3700 return main.ERROR
3701 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003702 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003703 return main.ERROR
3704 except TypeError:
3705 main.log.exception( self.name + ": Object not as expected" )
3706 return main.ERROR
3707 except pexpect.EOF:
3708 main.log.error( self.name + ": EOF exception found" )
3709 main.log.error( self.name + ": " + self.handle.before )
3710 main.cleanup()
3711 main.exit()
3712 except Exception:
3713 main.log.exception( self.name + ": Uncaught exception!" )
3714 main.cleanup()
3715 main.exit()
3716
3717 def setTestRemove( self, setName, values, clear=False, retain=False ):
3718 """
3719 CLI command to remove elements from a distributed set.
3720 Required arguments:
3721 setName - The name of the set to remove from.
3722 values - The value(s) to remove from the set, space seperated.
3723 Optional arguments:
3724 clear - Clear all elements from the set
3725 retain - Retain only the given values. (intersection of the
3726 original set and the given set)
3727 returns:
3728 main.TRUE on success OR
3729 main.FALSE if the set was not changed OR
3730 main.ERROR on error
3731 """
3732 try:
3733 cmdStr = "set-test-remove "
3734 if clear:
3735 cmdStr += "-c " + str( setName )
3736 elif retain:
3737 cmdStr += "-r " + str( setName ) + " " + str( values )
3738 else:
3739 cmdStr += str( setName ) + " " + str( values )
3740 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003741 try:
3742 # TODO: Maybe make this less hardcoded
3743 # ConsistentMap Exceptions
3744 assert "org.onosproject.store.service" not in output
3745 # Node not leader
3746 assert "java.lang.IllegalStateException" not in output
3747 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003748 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003749 "command: " + str( output ) )
3750 retryTime = 30 # Conservative time, given by Madan
3751 main.log.info( "Waiting " + str( retryTime ) +
3752 "seconds before retrying." )
3753 time.sleep( retryTime ) # Due to change in mastership
3754 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003755 assert "Command not found:" not in output, output
3756 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003757 main.log.info( self.name + ": " + output )
3758 if clear:
3759 pattern = "Set " + str( setName ) + " cleared"
3760 if re.search( pattern, output ):
3761 return main.TRUE
3762 elif retain:
3763 positivePattern = str( setName ) + " was pruned to contain " +\
3764 "only elements of set \[(.*)\]"
3765 negativePattern = str( setName ) + " was not changed by " +\
3766 "retaining only elements of the set " +\
3767 "\[(.*)\]"
3768 if re.search( positivePattern, output ):
3769 return main.TRUE
3770 elif re.search( negativePattern, output ):
3771 return main.FALSE
3772 else:
3773 positivePattern = "\[(.*)\] was removed from the set " +\
3774 str( setName )
3775 if ( len( values.split() ) == 1 ):
3776 negativePattern = "\[(.*)\] was not in set " +\
3777 str( setName )
3778 else:
3779 negativePattern = "No element of \[(.*)\] was in set " +\
3780 str( setName )
3781 if re.search( positivePattern, output ):
3782 return main.TRUE
3783 elif re.search( negativePattern, output ):
3784 return main.FALSE
3785 main.log.error( self.name + ": setTestRemove did not" +
3786 " match expected output" )
3787 main.log.debug( self.name + " expected: " + pattern )
3788 main.log.debug( self.name + " actual: " + repr( output ) )
3789 return main.ERROR
3790 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003791 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003792 return main.ERROR
3793 except TypeError:
3794 main.log.exception( self.name + ": Object not as expected" )
3795 return main.ERROR
3796 except pexpect.EOF:
3797 main.log.error( self.name + ": EOF exception found" )
3798 main.log.error( self.name + ": " + self.handle.before )
3799 main.cleanup()
3800 main.exit()
3801 except Exception:
3802 main.log.exception( self.name + ": Uncaught exception!" )
3803 main.cleanup()
3804 main.exit()
3805
3806 def setTestGet( self, setName, values="" ):
3807 """
3808 CLI command to get the elements in a distributed set.
3809 Required arguments:
3810 setName - The name of the set to remove from.
3811 Optional arguments:
3812 values - The value(s) to check if in the set, space seperated.
3813 returns:
3814 main.ERROR on error OR
3815 A list of elements in the set if no optional arguments are
3816 supplied OR
3817 A tuple containing the list then:
3818 main.FALSE if the given values are not in the set OR
3819 main.TRUE if the given values are in the set OR
3820 """
3821 try:
3822 values = str( values ).strip()
3823 setName = str( setName ).strip()
3824 length = len( values.split() )
3825 containsCheck = None
3826 # Patterns to match
3827 setPattern = "\[(.*)\]"
3828 pattern = "Items in set " + setName + ":\n" + setPattern
3829 containsTrue = "Set " + setName + " contains the value " + values
3830 containsFalse = "Set " + setName + " did not contain the value " +\
3831 values
3832 containsAllTrue = "Set " + setName + " contains the the subset " +\
3833 setPattern
3834 containsAllFalse = "Set " + setName + " did not contain the the" +\
3835 " subset " + setPattern
3836
3837 cmdStr = "set-test-get "
3838 cmdStr += setName + " " + values
3839 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003840 try:
3841 # TODO: Maybe make this less hardcoded
3842 # ConsistentMap Exceptions
3843 assert "org.onosproject.store.service" not in output
3844 # Node not leader
3845 assert "java.lang.IllegalStateException" not in output
3846 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003847 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003848 "command: " + str( output ) )
3849 retryTime = 30 # Conservative time, given by Madan
3850 main.log.info( "Waiting " + str( retryTime ) +
3851 "seconds before retrying." )
3852 time.sleep( retryTime ) # Due to change in mastership
3853 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003854 assert "Command not found:" not in output, output
3855 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003856 main.log.info( self.name + ": " + output )
3857
3858 if length == 0:
3859 match = re.search( pattern, output )
3860 else: # if given values
3861 if length == 1: # Contains output
3862 patternTrue = pattern + "\n" + containsTrue
3863 patternFalse = pattern + "\n" + containsFalse
3864 else: # ContainsAll output
3865 patternTrue = pattern + "\n" + containsAllTrue
3866 patternFalse = pattern + "\n" + containsAllFalse
3867 matchTrue = re.search( patternTrue, output )
3868 matchFalse = re.search( patternFalse, output )
3869 if matchTrue:
3870 containsCheck = main.TRUE
3871 match = matchTrue
3872 elif matchFalse:
3873 containsCheck = main.FALSE
3874 match = matchFalse
3875 else:
3876 main.log.error( self.name + " setTestGet did not match " +\
3877 "expected output" )
3878 main.log.debug( self.name + " expected: " + pattern )
3879 main.log.debug( self.name + " actual: " + repr( output ) )
3880 match = None
3881 if match:
3882 setMatch = match.group( 1 )
3883 if setMatch == '':
3884 setList = []
3885 else:
3886 setList = setMatch.split( ", " )
3887 if length > 0:
3888 return ( setList, containsCheck )
3889 else:
3890 return setList
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 main.ERROR
3897 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003898 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003899 return main.ERROR
3900 except TypeError:
3901 main.log.exception( self.name + ": Object not as expected" )
3902 return main.ERROR
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
3913 def setTestSize( self, setName ):
3914 """
3915 CLI command to get the elements in a distributed set.
3916 Required arguments:
3917 setName - The name of the set to remove from.
3918 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003919 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003920 None on error
3921 """
3922 try:
3923 # TODO: Should this check against the number of elements returned
3924 # and then return true/false based on that?
3925 setName = str( setName ).strip()
3926 # Patterns to match
3927 setPattern = "\[(.*)\]"
3928 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3929 setPattern
3930 cmdStr = "set-test-get -s "
3931 cmdStr += setName
3932 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003933 try:
3934 # TODO: Maybe make this less hardcoded
3935 # ConsistentMap Exceptions
3936 assert "org.onosproject.store.service" not in output
3937 # Node not leader
3938 assert "java.lang.IllegalStateException" not in output
3939 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003940 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003941 "command: " + str( output ) )
3942 retryTime = 30 # Conservative time, given by Madan
3943 main.log.info( "Waiting " + str( retryTime ) +
3944 "seconds before retrying." )
3945 time.sleep( retryTime ) # Due to change in mastership
3946 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003947 assert "Command not found:" not in output, output
3948 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003949 main.log.info( self.name + ": " + output )
3950 match = re.search( pattern, output )
3951 if match:
3952 setSize = int( match.group( 1 ) )
3953 setMatch = match.group( 2 )
3954 if len( setMatch.split() ) == setSize:
3955 main.log.info( "The size returned by " + self.name +
3956 " matches the number of elements in " +
3957 "the returned set" )
3958 else:
3959 main.log.error( "The size returned by " + self.name +
3960 " does not match the number of " +
3961 "elements in the returned set." )
3962 return setSize
3963 else: # no match
3964 main.log.error( self.name + ": setTestGet did not" +
3965 " match expected output" )
3966 main.log.debug( self.name + " expected: " + pattern )
3967 main.log.debug( self.name + " actual: " + repr( output ) )
3968 return None
3969 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003970 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003971 return None
Jon Hall390696c2015-05-05 17:13:41 -07003972 except TypeError:
3973 main.log.exception( self.name + ": Object not as expected" )
3974 return None
3975 except pexpect.EOF:
3976 main.log.error( self.name + ": EOF exception found" )
3977 main.log.error( self.name + ": " + self.handle.before )
3978 main.cleanup()
3979 main.exit()
3980 except Exception:
3981 main.log.exception( self.name + ": Uncaught exception!" )
3982 main.cleanup()
3983 main.exit()
3984
Jon Hall80daded2015-05-27 16:07:00 -07003985 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003986 """
3987 Command to list the various counters in the system.
3988 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003989 if jsonFormat, a string of the json object returned by the cli
3990 command
3991 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003992 None on error
3993 """
Jon Hall390696c2015-05-05 17:13:41 -07003994 try:
3995 counters = {}
3996 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003997 if jsonFormat:
3998 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003999 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004000 assert "Command not found:" not in output, output
4001 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004002 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004003 return output
Jon Hall390696c2015-05-05 17:13:41 -07004004 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004005 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004006 return None
Jon Hall390696c2015-05-05 17:13:41 -07004007 except TypeError:
4008 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004009 return None
Jon Hall390696c2015-05-05 17:13:41 -07004010 except pexpect.EOF:
4011 main.log.error( self.name + ": EOF exception found" )
4012 main.log.error( self.name + ": " + self.handle.before )
4013 main.cleanup()
4014 main.exit()
4015 except Exception:
4016 main.log.exception( self.name + ": Uncaught exception!" )
4017 main.cleanup()
4018 main.exit()
4019
Jon Halle1a3b752015-07-22 13:02:46 -07004020 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07004021 """
Jon Halle1a3b752015-07-22 13:02:46 -07004022 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004023 Required arguments:
4024 counter - The name of the counter to increment.
4025 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004026 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004027 inMemory - use in memory map for the counter
4028 returns:
4029 integer value of the counter or
4030 None on Error
4031 """
4032 try:
4033 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004034 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004035 cmdStr = "counter-test-increment "
4036 if inMemory:
4037 cmdStr += "-i "
4038 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004039 if delta != 1:
4040 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004041 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004042 try:
4043 # TODO: Maybe make this less hardcoded
4044 # ConsistentMap Exceptions
4045 assert "org.onosproject.store.service" not in output
4046 # Node not leader
4047 assert "java.lang.IllegalStateException" not in output
4048 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004049 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004050 "command: " + str( output ) )
4051 retryTime = 30 # Conservative time, given by Madan
4052 main.log.info( "Waiting " + str( retryTime ) +
4053 "seconds before retrying." )
4054 time.sleep( retryTime ) # Due to change in mastership
4055 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004056 assert "Command not found:" not in output, output
4057 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004058 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004059 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004060 match = re.search( pattern, output )
4061 if match:
4062 return int( match.group( 1 ) )
4063 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004064 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004065 " match expected output." )
4066 main.log.debug( self.name + " expected: " + pattern )
4067 main.log.debug( self.name + " actual: " + repr( output ) )
4068 return None
4069 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004070 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004071 return None
4072 except TypeError:
4073 main.log.exception( self.name + ": Object not as expected" )
4074 return None
4075 except pexpect.EOF:
4076 main.log.error( self.name + ": EOF exception found" )
4077 main.log.error( self.name + ": " + self.handle.before )
4078 main.cleanup()
4079 main.exit()
4080 except Exception:
4081 main.log.exception( self.name + ": Uncaught exception!" )
4082 main.cleanup()
4083 main.exit()
4084
Jon Halle1a3b752015-07-22 13:02:46 -07004085 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4086 """
4087 CLI command to get a distributed counter then add a delta to it.
4088 Required arguments:
4089 counter - The name of the counter to increment.
4090 Optional arguments:
4091 delta - The long to add to the counter
4092 inMemory - use in memory map for the counter
4093 returns:
4094 integer value of the counter or
4095 None on Error
4096 """
4097 try:
4098 counter = str( counter )
4099 delta = int( delta )
4100 cmdStr = "counter-test-increment -g "
4101 if inMemory:
4102 cmdStr += "-i "
4103 cmdStr += counter
4104 if delta != 1:
4105 cmdStr += " " + str( delta )
4106 output = self.sendline( cmdStr )
4107 try:
4108 # TODO: Maybe make this less hardcoded
4109 # ConsistentMap Exceptions
4110 assert "org.onosproject.store.service" not in output
4111 # Node not leader
4112 assert "java.lang.IllegalStateException" not in output
4113 except AssertionError:
4114 main.log.error( "Error in processing '" + cmdStr + "' " +
4115 "command: " + str( output ) )
4116 retryTime = 30 # Conservative time, given by Madan
4117 main.log.info( "Waiting " + str( retryTime ) +
4118 "seconds before retrying." )
4119 time.sleep( retryTime ) # Due to change in mastership
4120 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004121 assert "Command not found:" not in output, output
4122 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004123 main.log.info( self.name + ": " + output )
4124 pattern = counter + " was updated to (-?\d+)"
4125 match = re.search( pattern, output )
4126 if match:
4127 return int( match.group( 1 ) )
4128 else:
4129 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4130 " match expected output." )
4131 main.log.debug( self.name + " expected: " + pattern )
4132 main.log.debug( self.name + " actual: " + repr( output ) )
4133 return None
4134 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004135 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004136 return None
4137 except TypeError:
4138 main.log.exception( self.name + ": Object not as expected" )
4139 return None
4140 except pexpect.EOF:
4141 main.log.error( self.name + ": EOF exception found" )
4142 main.log.error( self.name + ": " + self.handle.before )
4143 main.cleanup()
4144 main.exit()
4145 except Exception:
4146 main.log.exception( self.name + ": Uncaught exception!" )
4147 main.cleanup()
4148 main.exit()
4149
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004150 def summary( self, jsonFormat=True ):
4151 """
4152 Description: Execute summary command in onos
4153 Returns: json object ( summary -j ), returns main.FALSE if there is
4154 no output
4155
4156 """
4157 try:
4158 cmdStr = "summary"
4159 if jsonFormat:
4160 cmdStr += " -j"
4161 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004162 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004163 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004164 if not handle:
4165 main.log.error( self.name + ": There is no output in " +
4166 "summary command" )
4167 return main.FALSE
4168 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004169 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004170 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004171 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004172 except TypeError:
4173 main.log.exception( self.name + ": Object not as expected" )
4174 return None
4175 except pexpect.EOF:
4176 main.log.error( self.name + ": EOF exception found" )
4177 main.log.error( self.name + ": " + self.handle.before )
4178 main.cleanup()
4179 main.exit()
4180 except Exception:
4181 main.log.exception( self.name + ": Uncaught exception!" )
4182 main.cleanup()
4183 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004184
4185 def transactionalMapGet( self, keyName, inMemory=False ):
4186 """
4187 CLI command to get the value of a key in a consistent map using
4188 transactions. This a test function and can only get keys from the
4189 test map hard coded into the cli command
4190 Required arguments:
4191 keyName - The name of the key to get
4192 Optional arguments:
4193 inMemory - use in memory map for the counter
4194 returns:
4195 The string value of the key or
4196 None on Error
4197 """
4198 try:
4199 keyName = str( keyName )
4200 cmdStr = "transactional-map-test-get "
4201 if inMemory:
4202 cmdStr += "-i "
4203 cmdStr += keyName
4204 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004205 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004206 try:
4207 # TODO: Maybe make this less hardcoded
4208 # ConsistentMap Exceptions
4209 assert "org.onosproject.store.service" not in output
4210 # Node not leader
4211 assert "java.lang.IllegalStateException" not in output
4212 except AssertionError:
4213 main.log.error( "Error in processing '" + cmdStr + "' " +
4214 "command: " + str( output ) )
4215 return None
4216 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4217 if "Key " + keyName + " not found." in output:
4218 return None
4219 else:
4220 match = re.search( pattern, output )
4221 if match:
4222 return match.groupdict()[ 'value' ]
4223 else:
4224 main.log.error( self.name + ": transactionlMapGet did not" +
4225 " match expected output." )
4226 main.log.debug( self.name + " expected: " + pattern )
4227 main.log.debug( self.name + " actual: " + repr( output ) )
4228 return None
Jon Hallc6793552016-01-19 14:18:37 -08004229 except AssertionError:
4230 main.log.exception( "" )
4231 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004232 except TypeError:
4233 main.log.exception( self.name + ": Object not as expected" )
4234 return None
4235 except pexpect.EOF:
4236 main.log.error( self.name + ": EOF exception found" )
4237 main.log.error( self.name + ": " + self.handle.before )
4238 main.cleanup()
4239 main.exit()
4240 except Exception:
4241 main.log.exception( self.name + ": Uncaught exception!" )
4242 main.cleanup()
4243 main.exit()
4244
4245 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4246 """
4247 CLI command to put a value into 'numKeys' number of keys in a
4248 consistent map using transactions. This a test function and can only
4249 put into keys named 'Key#' of the test map hard coded into the cli command
4250 Required arguments:
4251 numKeys - Number of keys to add the value to
4252 value - The string value to put into the keys
4253 Optional arguments:
4254 inMemory - use in memory map for the counter
4255 returns:
4256 A dictionary whose keys are the name of the keys put into the map
4257 and the values of the keys are dictionaries whose key-values are
4258 'value': value put into map and optionaly
4259 'oldValue': Previous value in the key or
4260 None on Error
4261
4262 Example output
4263 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4264 'Key2': {'value': 'Testing'} }
4265 """
4266 try:
4267 numKeys = str( numKeys )
4268 value = str( value )
4269 cmdStr = "transactional-map-test-put "
4270 if inMemory:
4271 cmdStr += "-i "
4272 cmdStr += numKeys + " " + value
4273 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004274 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004275 try:
4276 # TODO: Maybe make this less hardcoded
4277 # ConsistentMap Exceptions
4278 assert "org.onosproject.store.service" not in output
4279 # Node not leader
4280 assert "java.lang.IllegalStateException" not in output
4281 except AssertionError:
4282 main.log.error( "Error in processing '" + cmdStr + "' " +
4283 "command: " + str( output ) )
4284 return None
4285 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4286 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4287 results = {}
4288 for line in output.splitlines():
4289 new = re.search( newPattern, line )
4290 updated = re.search( updatedPattern, line )
4291 if new:
4292 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4293 elif updated:
4294 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004295 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004296 else:
4297 main.log.error( self.name + ": transactionlMapGet did not" +
4298 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004299 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4300 newPattern,
4301 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004302 main.log.debug( self.name + " actual: " + repr( output ) )
4303 return results
Jon Hallc6793552016-01-19 14:18:37 -08004304 except AssertionError:
4305 main.log.exception( "" )
4306 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004307 except TypeError:
4308 main.log.exception( self.name + ": Object not as expected" )
4309 return None
4310 except pexpect.EOF:
4311 main.log.error( self.name + ": EOF exception found" )
4312 main.log.error( self.name + ": " + self.handle.before )
4313 main.cleanup()
4314 main.exit()
4315 except Exception:
4316 main.log.exception( self.name + ": Uncaught exception!" )
4317 main.cleanup()
4318 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004319
acsmarsdaea66c2015-09-03 11:44:06 -07004320 def maps( self, jsonFormat=True ):
4321 """
4322 Description: Returns result of onos:maps
4323 Optional:
4324 * jsonFormat: enable json formatting of output
4325 """
4326 try:
4327 cmdStr = "maps"
4328 if jsonFormat:
4329 cmdStr += " -j"
4330 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004331 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004332 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004333 except AssertionError:
4334 main.log.exception( "" )
4335 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004336 except TypeError:
4337 main.log.exception( self.name + ": Object not as expected" )
4338 return None
4339 except pexpect.EOF:
4340 main.log.error( self.name + ": EOF exception found" )
4341 main.log.error( self.name + ": " + self.handle.before )
4342 main.cleanup()
4343 main.exit()
4344 except Exception:
4345 main.log.exception( self.name + ": Uncaught exception!" )
4346 main.cleanup()
4347 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004348
4349 def getSwController( self, uri, jsonFormat=True ):
4350 """
4351 Descrition: Gets the controller information from the device
4352 """
4353 try:
4354 cmd = "device-controllers "
4355 if jsonFormat:
4356 cmd += "-j "
4357 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004358 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004359 return response
Jon Hallc6793552016-01-19 14:18:37 -08004360 except AssertionError:
4361 main.log.exception( "" )
4362 return None
GlennRC050596c2015-11-18 17:06:41 -08004363 except TypeError:
4364 main.log.exception( self.name + ": Object not as expected" )
4365 return None
4366 except pexpect.EOF:
4367 main.log.error( self.name + ": EOF exception found" )
4368 main.log.error( self.name + ": " + self.handle.before )
4369 main.cleanup()
4370 main.exit()
4371 except Exception:
4372 main.log.exception( self.name + ": Uncaught exception!" )
4373 main.cleanup()
4374 main.exit()
4375
4376 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4377 """
4378 Descrition: sets the controller(s) for the specified device
4379
4380 Parameters:
4381 Required: uri - String: The uri of the device(switch).
4382 ip - String or List: The ip address of the controller.
4383 This parameter can be formed in a couple of different ways.
4384 VALID:
4385 10.0.0.1 - just the ip address
4386 tcp:10.0.0.1 - the protocol and the ip address
4387 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4388 so that you can add controllers with different
4389 protocols and ports
4390 INVALID:
4391 10.0.0.1:6653 - this is not supported by ONOS
4392
4393 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4394 port - The port number.
4395 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4396
4397 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4398 """
4399 try:
4400 cmd = "device-setcontrollers"
4401
4402 if jsonFormat:
4403 cmd += " -j"
4404 cmd += " " + uri
4405 if isinstance( ip, str ):
4406 ip = [ip]
4407 for item in ip:
4408 if ":" in item:
4409 sitem = item.split( ":" )
4410 if len(sitem) == 3:
4411 cmd += " " + item
4412 elif "." in sitem[1]:
4413 cmd += " {}:{}".format(item, port)
4414 else:
4415 main.log.error( "Malformed entry: " + item )
4416 raise TypeError
4417 else:
4418 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004419 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004420 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004421 if "Error" in response:
4422 main.log.error( response )
4423 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004424 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004425 except AssertionError:
4426 main.log.exception( "" )
4427 return None
GlennRC050596c2015-11-18 17:06:41 -08004428 except TypeError:
4429 main.log.exception( self.name + ": Object not as expected" )
4430 return main.FALSE
4431 except pexpect.EOF:
4432 main.log.error( self.name + ": EOF exception found" )
4433 main.log.error( self.name + ": " + self.handle.before )
4434 main.cleanup()
4435 main.exit()
4436 except Exception:
4437 main.log.exception( self.name + ": Uncaught exception!" )
4438 main.cleanup()
4439 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004440
4441 def removeDevice( self, device ):
4442 '''
4443 Description:
4444 Remove a device from ONOS by passing the uri of the device(s).
4445 Parameters:
4446 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4447 Returns:
4448 Returns main.FALSE if an exception is thrown or an error is present
4449 in the response. Otherwise, returns main.TRUE.
4450 NOTE:
4451 If a host cannot be removed, then this function will return main.FALSE
4452 '''
4453 try:
4454 if type( device ) is str:
4455 device = list( device )
4456
4457 for d in device:
4458 time.sleep( 1 )
4459 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004460 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004461 if "Error" in response:
4462 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4463 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004464 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004465 except AssertionError:
4466 main.log.exception( "" )
4467 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004468 except TypeError:
4469 main.log.exception( self.name + ": Object not as expected" )
4470 return main.FALSE
4471 except pexpect.EOF:
4472 main.log.error( self.name + ": EOF exception found" )
4473 main.log.error( self.name + ": " + self.handle.before )
4474 main.cleanup()
4475 main.exit()
4476 except Exception:
4477 main.log.exception( self.name + ": Uncaught exception!" )
4478 main.cleanup()
4479 main.exit()
4480
4481 def removeHost( self, host ):
4482 '''
4483 Description:
4484 Remove a host from ONOS by passing the id of the host(s)
4485 Parameters:
4486 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4487 Returns:
4488 Returns main.FALSE if an exception is thrown or an error is present
4489 in the response. Otherwise, returns main.TRUE.
4490 NOTE:
4491 If a host cannot be removed, then this function will return main.FALSE
4492 '''
4493 try:
4494 if type( host ) is str:
4495 host = list( host )
4496
4497 for h in host:
4498 time.sleep( 1 )
4499 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004500 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004501 if "Error" in response:
4502 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4503 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004504 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004505 except AssertionError:
4506 main.log.exception( "" )
4507 return None
GlennRC20fc6522015-12-23 23:26:57 -08004508 except TypeError:
4509 main.log.exception( self.name + ": Object not as expected" )
4510 return main.FALSE
4511 except pexpect.EOF:
4512 main.log.error( self.name + ": EOF exception found" )
4513 main.log.error( self.name + ": " + self.handle.before )
4514 main.cleanup()
4515 main.exit()
4516 except Exception:
4517 main.log.exception( self.name + ": Uncaught exception!" )
4518 main.cleanup()
4519 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004520
Jon Hallc6793552016-01-19 14:18:37 -08004521 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004522 '''
4523 Description:
4524 Bring link down or up in the null-provider.
4525 params:
4526 begin - (string) One end of a device or switch.
4527 end - (string) the other end of the device or switch
4528 returns:
4529 main.TRUE if no exceptions were thrown and no Errors are
4530 present in the resoponse. Otherwise, returns main.FALSE
4531 '''
4532 try:
Jon Hallc6793552016-01-19 14:18:37 -08004533 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004534 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004535 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004536 if "Error" in response or "Failure" in response:
4537 main.log.error( response )
4538 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004539 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004540 except AssertionError:
4541 main.log.exception( "" )
4542 return None
GlennRCed771242016-01-13 17:02:47 -08004543 except TypeError:
4544 main.log.exception( self.name + ": Object not as expected" )
4545 return main.FALSE
4546 except pexpect.EOF:
4547 main.log.error( self.name + ": EOF exception found" )
4548 main.log.error( self.name + ": " + self.handle.before )
4549 main.cleanup()
4550 main.exit()
4551 except Exception:
4552 main.log.exception( self.name + ": Uncaught exception!" )
4553 main.cleanup()
4554 main.exit()
4555