blob: ba2b37ce8f14576232ff93bce588fb53dde9f92d [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
2511 # id=local, address=127.0.0.1:9876, state=ACTIVE *
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
3286 # TODO: Check with Thomas about this delay
3287 status = self.appStatus( appName )
3288 if status == "ACTIVE":
3289 return main.TRUE
3290 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003291 main.log.debug( "The state of application " +
3292 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003293 time.sleep( 1 )
3294 return main.FALSE
3295 else: # not 'check' or command didn't succeed
3296 return response
Jon Hall146f1522015-03-24 15:33:24 -07003297 elif status == "ACTIVE":
3298 return main.TRUE
3299 elif status == "UNINSTALLED":
3300 main.log.error( self.name + ": Tried to activate the " +
3301 "application '" + appName + "' which is not " +
3302 "installed." )
3303 else:
3304 main.log.error( "Unexpected return value from appStatus: " +
3305 str( status ) )
3306 return main.ERROR
3307 except TypeError:
3308 main.log.exception( self.name + ": Object not as expected" )
3309 return main.ERROR
3310 except pexpect.EOF:
3311 main.log.error( self.name + ": EOF exception found" )
3312 main.log.error( self.name + ": " + self.handle.before )
3313 main.cleanup()
3314 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003315 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003316 main.log.exception( self.name + ": Uncaught exception!" )
3317 main.cleanup()
3318 main.exit()
3319
Jon Hallbd16b922015-03-26 17:53:15 -07003320 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003321 """
3322 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003323 appName is the hierarchical app name, not the feature name
3324 If check is True, method will check the status of the app after the
3325 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003326 Returns main.TRUE if the command was successfully sent
3327 main.FALSE if the cli responded with an error or given
3328 incorrect input
3329 """
3330 try:
3331 if not isinstance( appName, types.StringType ):
3332 main.log.error( self.name + ".deactivateApp(): appName must " +
3333 "be a string" )
3334 return main.FALSE
3335 status = self.appStatus( appName )
3336 if status == "INSTALLED":
3337 return main.TRUE
3338 elif status == "ACTIVE":
3339 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003340 if check and response == main.TRUE:
3341 for i in range(10): # try 10 times then give up
3342 status = self.appStatus( appName )
3343 if status == "INSTALLED":
3344 return main.TRUE
3345 else:
3346 time.sleep( 1 )
3347 return main.FALSE
3348 else: # not check or command didn't succeed
3349 return response
Jon Hall146f1522015-03-24 15:33:24 -07003350 elif status == "UNINSTALLED":
3351 main.log.warn( self.name + ": Tried to deactivate the " +
3352 "application '" + appName + "' which is not " +
3353 "installed." )
3354 return main.TRUE
3355 else:
3356 main.log.error( "Unexpected return value from appStatus: " +
3357 str( status ) )
3358 return main.ERROR
3359 except TypeError:
3360 main.log.exception( self.name + ": Object not as expected" )
3361 return main.ERROR
3362 except pexpect.EOF:
3363 main.log.error( self.name + ": EOF exception found" )
3364 main.log.error( self.name + ": " + self.handle.before )
3365 main.cleanup()
3366 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003367 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003368 main.log.exception( self.name + ": Uncaught exception!" )
3369 main.cleanup()
3370 main.exit()
3371
Jon Hallbd16b922015-03-26 17:53:15 -07003372 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003373 """
3374 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003375 appName is the hierarchical app name, not the feature name
3376 If check is True, method will check the status of the app after the
3377 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003378 Returns main.TRUE if the command was successfully sent
3379 main.FALSE if the cli responded with an error or given
3380 incorrect input
3381 """
3382 # TODO: check with Thomas about the state machine for apps
3383 try:
3384 if not isinstance( appName, types.StringType ):
3385 main.log.error( self.name + ".uninstallApp(): appName must " +
3386 "be a string" )
3387 return main.FALSE
3388 status = self.appStatus( appName )
3389 if status == "INSTALLED":
3390 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003391 if check and response == main.TRUE:
3392 for i in range(10): # try 10 times then give up
3393 status = self.appStatus( appName )
3394 if status == "UNINSTALLED":
3395 return main.TRUE
3396 else:
3397 time.sleep( 1 )
3398 return main.FALSE
3399 else: # not check or command didn't succeed
3400 return response
Jon Hall146f1522015-03-24 15:33:24 -07003401 elif status == "ACTIVE":
3402 main.log.warn( self.name + ": Tried to uninstall the " +
3403 "application '" + appName + "' which is " +
3404 "currently active." )
3405 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003406 if check and response == main.TRUE:
3407 for i in range(10): # try 10 times then give up
3408 status = self.appStatus( appName )
3409 if status == "UNINSTALLED":
3410 return main.TRUE
3411 else:
3412 time.sleep( 1 )
3413 return main.FALSE
3414 else: # not check or command didn't succeed
3415 return response
Jon Hall146f1522015-03-24 15:33:24 -07003416 elif status == "UNINSTALLED":
3417 return main.TRUE
3418 else:
3419 main.log.error( "Unexpected return value from appStatus: " +
3420 str( status ) )
3421 return main.ERROR
3422 except TypeError:
3423 main.log.exception( self.name + ": Object not as expected" )
3424 return main.ERROR
3425 except pexpect.EOF:
3426 main.log.error( self.name + ": EOF exception found" )
3427 main.log.error( self.name + ": " + self.handle.before )
3428 main.cleanup()
3429 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003430 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003431 main.log.exception( self.name + ": Uncaught exception!" )
3432 main.cleanup()
3433 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003434
3435 def appIDs( self, jsonFormat=True ):
3436 """
3437 Show the mappings between app id and app names given by the 'app-ids'
3438 cli command
3439 """
3440 try:
3441 cmdStr = "app-ids"
3442 if jsonFormat:
3443 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003444 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003445 assert "Command not found:" not in output, output
3446 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003447 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003448 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003449 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003450 return None
3451 except TypeError:
3452 main.log.exception( self.name + ": Object not as expected" )
3453 return None
3454 except pexpect.EOF:
3455 main.log.error( self.name + ": EOF exception found" )
3456 main.log.error( self.name + ": " + self.handle.before )
3457 main.cleanup()
3458 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003459 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003460 main.log.exception( self.name + ": Uncaught exception!" )
3461 main.cleanup()
3462 main.exit()
3463
3464 def appToIDCheck( self ):
3465 """
3466 This method will check that each application's ID listed in 'apps' is
3467 the same as the ID listed in 'app-ids'. The check will also check that
3468 there are no duplicate IDs issued. Note that an app ID should be
3469 a globaly unique numerical identifier for app/app-like features. Once
3470 an ID is registered, the ID is never freed up so that if an app is
3471 reinstalled it will have the same ID.
3472
3473 Returns: main.TRUE if the check passes and
3474 main.FALSE if the check fails or
3475 main.ERROR if there is some error in processing the test
3476 """
3477 try:
Jon Hall390696c2015-05-05 17:13:41 -07003478 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003479 rawJson = self.appIDs( jsonFormat=True )
3480 if rawJson:
3481 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003482 else:
Jon Hallc6793552016-01-19 14:18:37 -08003483 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003484 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003485 rawJson = self.apps( jsonFormat=True )
3486 if rawJson:
3487 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003488 else:
Jon Hallc6793552016-01-19 14:18:37 -08003489 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003490 bail = True
3491 if bail:
3492 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003493 result = main.TRUE
3494 for app in apps:
3495 appID = app.get( 'id' )
3496 if appID is None:
3497 main.log.error( "Error parsing app: " + str( app ) )
3498 result = main.FALSE
3499 appName = app.get( 'name' )
3500 if appName is None:
3501 main.log.error( "Error parsing app: " + str( app ) )
3502 result = main.FALSE
3503 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003504 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003505 # main.log.debug( "Comparing " + str( app ) + " to " +
3506 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003507 if not current: # if ids doesn't have this id
3508 result = main.FALSE
3509 main.log.error( "'app-ids' does not have the ID for " +
3510 str( appName ) + " that apps does." )
3511 elif len( current ) > 1:
3512 # there is more than one app with this ID
3513 result = main.FALSE
3514 # We will log this later in the method
3515 elif not current[0][ 'name' ] == appName:
3516 currentName = current[0][ 'name' ]
3517 result = main.FALSE
3518 main.log.error( "'app-ids' has " + str( currentName ) +
3519 " registered under id:" + str( appID ) +
3520 " but 'apps' has " + str( appName ) )
3521 else:
3522 pass # id and name match!
3523 # now make sure that app-ids has no duplicates
3524 idsList = []
3525 namesList = []
3526 for item in ids:
3527 idsList.append( item[ 'id' ] )
3528 namesList.append( item[ 'name' ] )
3529 if len( idsList ) != len( set( idsList ) ) or\
3530 len( namesList ) != len( set( namesList ) ):
3531 main.log.error( "'app-ids' has some duplicate entries: \n"
3532 + json.dumps( ids,
3533 sort_keys=True,
3534 indent=4,
3535 separators=( ',', ': ' ) ) )
3536 result = main.FALSE
3537 return result
Jon Hallc6793552016-01-19 14:18:37 -08003538 except ( TypeError, ValueError ):
3539 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003540 return main.ERROR
3541 except pexpect.EOF:
3542 main.log.error( self.name + ": EOF exception found" )
3543 main.log.error( self.name + ": " + self.handle.before )
3544 main.cleanup()
3545 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003546 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003547 main.log.exception( self.name + ": Uncaught exception!" )
3548 main.cleanup()
3549 main.exit()
3550
Jon Hallfb760a02015-04-13 15:35:03 -07003551 def getCfg( self, component=None, propName=None, short=False,
3552 jsonFormat=True ):
3553 """
3554 Get configuration settings from onos cli
3555 Optional arguments:
3556 component - Optionally only list configurations for a specific
3557 component. If None, all components with configurations
3558 are displayed. Case Sensitive string.
3559 propName - If component is specified, propName option will show
3560 only this specific configuration from that component.
3561 Case Sensitive string.
3562 jsonFormat - Returns output as json. Note that this will override
3563 the short option
3564 short - Short, less verbose, version of configurations.
3565 This is overridden by the json option
3566 returns:
3567 Output from cli as a string or None on error
3568 """
3569 try:
3570 baseStr = "cfg"
3571 cmdStr = " get"
3572 componentStr = ""
3573 if component:
3574 componentStr += " " + component
3575 if propName:
3576 componentStr += " " + propName
3577 if jsonFormat:
3578 baseStr += " -j"
3579 elif short:
3580 baseStr += " -s"
3581 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003582 assert "Command not found:" not in output, output
3583 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003584 return output
3585 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003586 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003587 return None
3588 except TypeError:
3589 main.log.exception( self.name + ": Object not as expected" )
3590 return None
3591 except pexpect.EOF:
3592 main.log.error( self.name + ": EOF exception found" )
3593 main.log.error( self.name + ": " + self.handle.before )
3594 main.cleanup()
3595 main.exit()
3596 except Exception:
3597 main.log.exception( self.name + ": Uncaught exception!" )
3598 main.cleanup()
3599 main.exit()
3600
3601 def setCfg( self, component, propName, value=None, check=True ):
3602 """
3603 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003604 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003605 component - The case sensitive name of the component whose
3606 property is to be set
3607 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003608 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003609 value - The value to set the property to. If None, will unset the
3610 property and revert it to it's default value(if applicable)
3611 check - Boolean, Check whether the option was successfully set this
3612 only applies when a value is given.
3613 returns:
3614 main.TRUE on success or main.FALSE on failure. If check is False,
3615 will return main.TRUE unless there is an error
3616 """
3617 try:
3618 baseStr = "cfg"
3619 cmdStr = " set " + str( component ) + " " + str( propName )
3620 if value is not None:
3621 cmdStr += " " + str( value )
3622 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003623 assert "Command not found:" not in output, output
3624 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003625 if value and check:
3626 results = self.getCfg( component=str( component ),
3627 propName=str( propName ),
3628 jsonFormat=True )
3629 # Check if current value is what we just set
3630 try:
3631 jsonOutput = json.loads( results )
3632 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003633 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003634 main.log.exception( "Error parsing cfg output" )
3635 main.log.error( "output:" + repr( results ) )
3636 return main.FALSE
3637 if current == str( value ):
3638 return main.TRUE
3639 return main.FALSE
3640 return main.TRUE
3641 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003642 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003643 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003644 except ( TypeError, ValueError ):
3645 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003646 return main.FALSE
3647 except pexpect.EOF:
3648 main.log.error( self.name + ": EOF exception found" )
3649 main.log.error( self.name + ": " + self.handle.before )
3650 main.cleanup()
3651 main.exit()
3652 except Exception:
3653 main.log.exception( self.name + ": Uncaught exception!" )
3654 main.cleanup()
3655 main.exit()
3656
Jon Hall390696c2015-05-05 17:13:41 -07003657 def setTestAdd( self, setName, values ):
3658 """
3659 CLI command to add elements to a distributed set.
3660 Arguments:
3661 setName - The name of the set to add to.
3662 values - The value(s) to add to the set, space seperated.
3663 Example usages:
3664 setTestAdd( "set1", "a b c" )
3665 setTestAdd( "set2", "1" )
3666 returns:
3667 main.TRUE on success OR
3668 main.FALSE if elements were already in the set OR
3669 main.ERROR on error
3670 """
3671 try:
3672 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3673 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003674 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003675 try:
3676 # TODO: Maybe make this less hardcoded
3677 # ConsistentMap Exceptions
3678 assert "org.onosproject.store.service" not in output
3679 # Node not leader
3680 assert "java.lang.IllegalStateException" not in output
3681 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003682 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003683 "command: " + str( output ) )
3684 retryTime = 30 # Conservative time, given by Madan
3685 main.log.info( "Waiting " + str( retryTime ) +
3686 "seconds before retrying." )
3687 time.sleep( retryTime ) # Due to change in mastership
3688 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003689 assert "Error executing command" not in output
3690 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3691 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3692 main.log.info( self.name + ": " + output )
3693 if re.search( positiveMatch, output):
3694 return main.TRUE
3695 elif re.search( negativeMatch, output):
3696 return main.FALSE
3697 else:
3698 main.log.error( self.name + ": setTestAdd did not" +
3699 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003700 main.log.debug( self.name + " actual: " + repr( output ) )
3701 return main.ERROR
3702 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003703 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003704 return main.ERROR
3705 except TypeError:
3706 main.log.exception( self.name + ": Object not as expected" )
3707 return main.ERROR
3708 except pexpect.EOF:
3709 main.log.error( self.name + ": EOF exception found" )
3710 main.log.error( self.name + ": " + self.handle.before )
3711 main.cleanup()
3712 main.exit()
3713 except Exception:
3714 main.log.exception( self.name + ": Uncaught exception!" )
3715 main.cleanup()
3716 main.exit()
3717
3718 def setTestRemove( self, setName, values, clear=False, retain=False ):
3719 """
3720 CLI command to remove elements from a distributed set.
3721 Required arguments:
3722 setName - The name of the set to remove from.
3723 values - The value(s) to remove from the set, space seperated.
3724 Optional arguments:
3725 clear - Clear all elements from the set
3726 retain - Retain only the given values. (intersection of the
3727 original set and the given set)
3728 returns:
3729 main.TRUE on success OR
3730 main.FALSE if the set was not changed OR
3731 main.ERROR on error
3732 """
3733 try:
3734 cmdStr = "set-test-remove "
3735 if clear:
3736 cmdStr += "-c " + str( setName )
3737 elif retain:
3738 cmdStr += "-r " + str( setName ) + " " + str( values )
3739 else:
3740 cmdStr += str( setName ) + " " + str( values )
3741 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003742 try:
3743 # TODO: Maybe make this less hardcoded
3744 # ConsistentMap Exceptions
3745 assert "org.onosproject.store.service" not in output
3746 # Node not leader
3747 assert "java.lang.IllegalStateException" not in output
3748 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003749 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003750 "command: " + str( output ) )
3751 retryTime = 30 # Conservative time, given by Madan
3752 main.log.info( "Waiting " + str( retryTime ) +
3753 "seconds before retrying." )
3754 time.sleep( retryTime ) # Due to change in mastership
3755 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003756 assert "Command not found:" not in output, output
3757 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003758 main.log.info( self.name + ": " + output )
3759 if clear:
3760 pattern = "Set " + str( setName ) + " cleared"
3761 if re.search( pattern, output ):
3762 return main.TRUE
3763 elif retain:
3764 positivePattern = str( setName ) + " was pruned to contain " +\
3765 "only elements of set \[(.*)\]"
3766 negativePattern = str( setName ) + " was not changed by " +\
3767 "retaining only elements of the set " +\
3768 "\[(.*)\]"
3769 if re.search( positivePattern, output ):
3770 return main.TRUE
3771 elif re.search( negativePattern, output ):
3772 return main.FALSE
3773 else:
3774 positivePattern = "\[(.*)\] was removed from the set " +\
3775 str( setName )
3776 if ( len( values.split() ) == 1 ):
3777 negativePattern = "\[(.*)\] was not in set " +\
3778 str( setName )
3779 else:
3780 negativePattern = "No element of \[(.*)\] was in set " +\
3781 str( setName )
3782 if re.search( positivePattern, output ):
3783 return main.TRUE
3784 elif re.search( negativePattern, output ):
3785 return main.FALSE
3786 main.log.error( self.name + ": setTestRemove did not" +
3787 " match expected output" )
3788 main.log.debug( self.name + " expected: " + pattern )
3789 main.log.debug( self.name + " actual: " + repr( output ) )
3790 return main.ERROR
3791 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003792 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003793 return main.ERROR
3794 except TypeError:
3795 main.log.exception( self.name + ": Object not as expected" )
3796 return main.ERROR
3797 except pexpect.EOF:
3798 main.log.error( self.name + ": EOF exception found" )
3799 main.log.error( self.name + ": " + self.handle.before )
3800 main.cleanup()
3801 main.exit()
3802 except Exception:
3803 main.log.exception( self.name + ": Uncaught exception!" )
3804 main.cleanup()
3805 main.exit()
3806
3807 def setTestGet( self, setName, values="" ):
3808 """
3809 CLI command to get the elements in a distributed set.
3810 Required arguments:
3811 setName - The name of the set to remove from.
3812 Optional arguments:
3813 values - The value(s) to check if in the set, space seperated.
3814 returns:
3815 main.ERROR on error OR
3816 A list of elements in the set if no optional arguments are
3817 supplied OR
3818 A tuple containing the list then:
3819 main.FALSE if the given values are not in the set OR
3820 main.TRUE if the given values are in the set OR
3821 """
3822 try:
3823 values = str( values ).strip()
3824 setName = str( setName ).strip()
3825 length = len( values.split() )
3826 containsCheck = None
3827 # Patterns to match
3828 setPattern = "\[(.*)\]"
3829 pattern = "Items in set " + setName + ":\n" + setPattern
3830 containsTrue = "Set " + setName + " contains the value " + values
3831 containsFalse = "Set " + setName + " did not contain the value " +\
3832 values
3833 containsAllTrue = "Set " + setName + " contains the the subset " +\
3834 setPattern
3835 containsAllFalse = "Set " + setName + " did not contain the the" +\
3836 " subset " + setPattern
3837
3838 cmdStr = "set-test-get "
3839 cmdStr += setName + " " + values
3840 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003841 try:
3842 # TODO: Maybe make this less hardcoded
3843 # ConsistentMap Exceptions
3844 assert "org.onosproject.store.service" not in output
3845 # Node not leader
3846 assert "java.lang.IllegalStateException" not in output
3847 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003848 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003849 "command: " + str( output ) )
3850 retryTime = 30 # Conservative time, given by Madan
3851 main.log.info( "Waiting " + str( retryTime ) +
3852 "seconds before retrying." )
3853 time.sleep( retryTime ) # Due to change in mastership
3854 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003855 assert "Command not found:" not in output, output
3856 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003857 main.log.info( self.name + ": " + output )
3858
3859 if length == 0:
3860 match = re.search( pattern, output )
3861 else: # if given values
3862 if length == 1: # Contains output
3863 patternTrue = pattern + "\n" + containsTrue
3864 patternFalse = pattern + "\n" + containsFalse
3865 else: # ContainsAll output
3866 patternTrue = pattern + "\n" + containsAllTrue
3867 patternFalse = pattern + "\n" + containsAllFalse
3868 matchTrue = re.search( patternTrue, output )
3869 matchFalse = re.search( patternFalse, output )
3870 if matchTrue:
3871 containsCheck = main.TRUE
3872 match = matchTrue
3873 elif matchFalse:
3874 containsCheck = main.FALSE
3875 match = matchFalse
3876 else:
3877 main.log.error( self.name + " setTestGet did not match " +\
3878 "expected output" )
3879 main.log.debug( self.name + " expected: " + pattern )
3880 main.log.debug( self.name + " actual: " + repr( output ) )
3881 match = None
3882 if match:
3883 setMatch = match.group( 1 )
3884 if setMatch == '':
3885 setList = []
3886 else:
3887 setList = setMatch.split( ", " )
3888 if length > 0:
3889 return ( setList, containsCheck )
3890 else:
3891 return setList
3892 else: # no match
3893 main.log.error( self.name + ": setTestGet did not" +
3894 " match expected output" )
3895 main.log.debug( self.name + " expected: " + pattern )
3896 main.log.debug( self.name + " actual: " + repr( output ) )
3897 return main.ERROR
3898 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003899 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003900 return main.ERROR
3901 except TypeError:
3902 main.log.exception( self.name + ": Object not as expected" )
3903 return main.ERROR
3904 except pexpect.EOF:
3905 main.log.error( self.name + ": EOF exception found" )
3906 main.log.error( self.name + ": " + self.handle.before )
3907 main.cleanup()
3908 main.exit()
3909 except Exception:
3910 main.log.exception( self.name + ": Uncaught exception!" )
3911 main.cleanup()
3912 main.exit()
3913
3914 def setTestSize( self, setName ):
3915 """
3916 CLI command to get the elements in a distributed set.
3917 Required arguments:
3918 setName - The name of the set to remove from.
3919 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003920 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003921 None on error
3922 """
3923 try:
3924 # TODO: Should this check against the number of elements returned
3925 # and then return true/false based on that?
3926 setName = str( setName ).strip()
3927 # Patterns to match
3928 setPattern = "\[(.*)\]"
3929 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3930 setPattern
3931 cmdStr = "set-test-get -s "
3932 cmdStr += setName
3933 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003934 try:
3935 # TODO: Maybe make this less hardcoded
3936 # ConsistentMap Exceptions
3937 assert "org.onosproject.store.service" not in output
3938 # Node not leader
3939 assert "java.lang.IllegalStateException" not in output
3940 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003941 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003942 "command: " + str( output ) )
3943 retryTime = 30 # Conservative time, given by Madan
3944 main.log.info( "Waiting " + str( retryTime ) +
3945 "seconds before retrying." )
3946 time.sleep( retryTime ) # Due to change in mastership
3947 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003948 assert "Command not found:" not in output, output
3949 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003950 main.log.info( self.name + ": " + output )
3951 match = re.search( pattern, output )
3952 if match:
3953 setSize = int( match.group( 1 ) )
3954 setMatch = match.group( 2 )
3955 if len( setMatch.split() ) == setSize:
3956 main.log.info( "The size returned by " + self.name +
3957 " matches the number of elements in " +
3958 "the returned set" )
3959 else:
3960 main.log.error( "The size returned by " + self.name +
3961 " does not match the number of " +
3962 "elements in the returned set." )
3963 return setSize
3964 else: # no match
3965 main.log.error( self.name + ": setTestGet did not" +
3966 " match expected output" )
3967 main.log.debug( self.name + " expected: " + pattern )
3968 main.log.debug( self.name + " actual: " + repr( output ) )
3969 return None
3970 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003971 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003972 return None
Jon Hall390696c2015-05-05 17:13:41 -07003973 except TypeError:
3974 main.log.exception( self.name + ": Object not as expected" )
3975 return None
3976 except pexpect.EOF:
3977 main.log.error( self.name + ": EOF exception found" )
3978 main.log.error( self.name + ": " + self.handle.before )
3979 main.cleanup()
3980 main.exit()
3981 except Exception:
3982 main.log.exception( self.name + ": Uncaught exception!" )
3983 main.cleanup()
3984 main.exit()
3985
Jon Hall80daded2015-05-27 16:07:00 -07003986 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003987 """
3988 Command to list the various counters in the system.
3989 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003990 if jsonFormat, a string of the json object returned by the cli
3991 command
3992 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003993 None on error
3994 """
Jon Hall390696c2015-05-05 17:13:41 -07003995 try:
3996 counters = {}
3997 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003998 if jsonFormat:
3999 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004000 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004001 assert "Command not found:" not in output, output
4002 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004003 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004004 return output
Jon Hall390696c2015-05-05 17:13:41 -07004005 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004006 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004007 return None
Jon Hall390696c2015-05-05 17:13:41 -07004008 except TypeError:
4009 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004010 return None
Jon Hall390696c2015-05-05 17:13:41 -07004011 except pexpect.EOF:
4012 main.log.error( self.name + ": EOF exception found" )
4013 main.log.error( self.name + ": " + self.handle.before )
4014 main.cleanup()
4015 main.exit()
4016 except Exception:
4017 main.log.exception( self.name + ": Uncaught exception!" )
4018 main.cleanup()
4019 main.exit()
4020
Jon Halle1a3b752015-07-22 13:02:46 -07004021 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07004022 """
Jon Halle1a3b752015-07-22 13:02:46 -07004023 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004024 Required arguments:
4025 counter - The name of the counter to increment.
4026 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004027 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004028 inMemory - use in memory map for the counter
4029 returns:
4030 integer value of the counter or
4031 None on Error
4032 """
4033 try:
4034 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004035 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004036 cmdStr = "counter-test-increment "
4037 if inMemory:
4038 cmdStr += "-i "
4039 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004040 if delta != 1:
4041 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004042 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004043 try:
4044 # TODO: Maybe make this less hardcoded
4045 # ConsistentMap Exceptions
4046 assert "org.onosproject.store.service" not in output
4047 # Node not leader
4048 assert "java.lang.IllegalStateException" not in output
4049 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004050 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004051 "command: " + str( output ) )
4052 retryTime = 30 # Conservative time, given by Madan
4053 main.log.info( "Waiting " + str( retryTime ) +
4054 "seconds before retrying." )
4055 time.sleep( retryTime ) # Due to change in mastership
4056 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004057 assert "Command not found:" not in output, output
4058 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004059 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004060 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004061 match = re.search( pattern, output )
4062 if match:
4063 return int( match.group( 1 ) )
4064 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004065 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004066 " match expected output." )
4067 main.log.debug( self.name + " expected: " + pattern )
4068 main.log.debug( self.name + " actual: " + repr( output ) )
4069 return None
4070 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004071 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004072 return None
4073 except TypeError:
4074 main.log.exception( self.name + ": Object not as expected" )
4075 return None
4076 except pexpect.EOF:
4077 main.log.error( self.name + ": EOF exception found" )
4078 main.log.error( self.name + ": " + self.handle.before )
4079 main.cleanup()
4080 main.exit()
4081 except Exception:
4082 main.log.exception( self.name + ": Uncaught exception!" )
4083 main.cleanup()
4084 main.exit()
4085
Jon Halle1a3b752015-07-22 13:02:46 -07004086 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4087 """
4088 CLI command to get a distributed counter then add a delta to it.
4089 Required arguments:
4090 counter - The name of the counter to increment.
4091 Optional arguments:
4092 delta - The long to add to the counter
4093 inMemory - use in memory map for the counter
4094 returns:
4095 integer value of the counter or
4096 None on Error
4097 """
4098 try:
4099 counter = str( counter )
4100 delta = int( delta )
4101 cmdStr = "counter-test-increment -g "
4102 if inMemory:
4103 cmdStr += "-i "
4104 cmdStr += counter
4105 if delta != 1:
4106 cmdStr += " " + str( delta )
4107 output = self.sendline( cmdStr )
4108 try:
4109 # TODO: Maybe make this less hardcoded
4110 # ConsistentMap Exceptions
4111 assert "org.onosproject.store.service" not in output
4112 # Node not leader
4113 assert "java.lang.IllegalStateException" not in output
4114 except AssertionError:
4115 main.log.error( "Error in processing '" + cmdStr + "' " +
4116 "command: " + str( output ) )
4117 retryTime = 30 # Conservative time, given by Madan
4118 main.log.info( "Waiting " + str( retryTime ) +
4119 "seconds before retrying." )
4120 time.sleep( retryTime ) # Due to change in mastership
4121 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004122 assert "Command not found:" not in output, output
4123 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004124 main.log.info( self.name + ": " + output )
4125 pattern = counter + " was updated to (-?\d+)"
4126 match = re.search( pattern, output )
4127 if match:
4128 return int( match.group( 1 ) )
4129 else:
4130 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4131 " match expected output." )
4132 main.log.debug( self.name + " expected: " + pattern )
4133 main.log.debug( self.name + " actual: " + repr( output ) )
4134 return None
4135 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004136 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004137 return None
4138 except TypeError:
4139 main.log.exception( self.name + ": Object not as expected" )
4140 return None
4141 except pexpect.EOF:
4142 main.log.error( self.name + ": EOF exception found" )
4143 main.log.error( self.name + ": " + self.handle.before )
4144 main.cleanup()
4145 main.exit()
4146 except Exception:
4147 main.log.exception( self.name + ": Uncaught exception!" )
4148 main.cleanup()
4149 main.exit()
4150
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004151 def summary( self, jsonFormat=True ):
4152 """
4153 Description: Execute summary command in onos
4154 Returns: json object ( summary -j ), returns main.FALSE if there is
4155 no output
4156
4157 """
4158 try:
4159 cmdStr = "summary"
4160 if jsonFormat:
4161 cmdStr += " -j"
4162 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004163 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004164 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004165 if not handle:
4166 main.log.error( self.name + ": There is no output in " +
4167 "summary command" )
4168 return main.FALSE
4169 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004170 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004171 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004172 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004173 except TypeError:
4174 main.log.exception( self.name + ": Object not as expected" )
4175 return None
4176 except pexpect.EOF:
4177 main.log.error( self.name + ": EOF exception found" )
4178 main.log.error( self.name + ": " + self.handle.before )
4179 main.cleanup()
4180 main.exit()
4181 except Exception:
4182 main.log.exception( self.name + ": Uncaught exception!" )
4183 main.cleanup()
4184 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004185
4186 def transactionalMapGet( self, keyName, inMemory=False ):
4187 """
4188 CLI command to get the value of a key in a consistent map using
4189 transactions. This a test function and can only get keys from the
4190 test map hard coded into the cli command
4191 Required arguments:
4192 keyName - The name of the key to get
4193 Optional arguments:
4194 inMemory - use in memory map for the counter
4195 returns:
4196 The string value of the key or
4197 None on Error
4198 """
4199 try:
4200 keyName = str( keyName )
4201 cmdStr = "transactional-map-test-get "
4202 if inMemory:
4203 cmdStr += "-i "
4204 cmdStr += keyName
4205 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004206 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004207 try:
4208 # TODO: Maybe make this less hardcoded
4209 # ConsistentMap Exceptions
4210 assert "org.onosproject.store.service" not in output
4211 # Node not leader
4212 assert "java.lang.IllegalStateException" not in output
4213 except AssertionError:
4214 main.log.error( "Error in processing '" + cmdStr + "' " +
4215 "command: " + str( output ) )
4216 return None
4217 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4218 if "Key " + keyName + " not found." in output:
4219 return None
4220 else:
4221 match = re.search( pattern, output )
4222 if match:
4223 return match.groupdict()[ 'value' ]
4224 else:
4225 main.log.error( self.name + ": transactionlMapGet did not" +
4226 " match expected output." )
4227 main.log.debug( self.name + " expected: " + pattern )
4228 main.log.debug( self.name + " actual: " + repr( output ) )
4229 return None
Jon Hallc6793552016-01-19 14:18:37 -08004230 except AssertionError:
4231 main.log.exception( "" )
4232 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004233 except TypeError:
4234 main.log.exception( self.name + ": Object not as expected" )
4235 return None
4236 except pexpect.EOF:
4237 main.log.error( self.name + ": EOF exception found" )
4238 main.log.error( self.name + ": " + self.handle.before )
4239 main.cleanup()
4240 main.exit()
4241 except Exception:
4242 main.log.exception( self.name + ": Uncaught exception!" )
4243 main.cleanup()
4244 main.exit()
4245
4246 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4247 """
4248 CLI command to put a value into 'numKeys' number of keys in a
4249 consistent map using transactions. This a test function and can only
4250 put into keys named 'Key#' of the test map hard coded into the cli command
4251 Required arguments:
4252 numKeys - Number of keys to add the value to
4253 value - The string value to put into the keys
4254 Optional arguments:
4255 inMemory - use in memory map for the counter
4256 returns:
4257 A dictionary whose keys are the name of the keys put into the map
4258 and the values of the keys are dictionaries whose key-values are
4259 'value': value put into map and optionaly
4260 'oldValue': Previous value in the key or
4261 None on Error
4262
4263 Example output
4264 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4265 'Key2': {'value': 'Testing'} }
4266 """
4267 try:
4268 numKeys = str( numKeys )
4269 value = str( value )
4270 cmdStr = "transactional-map-test-put "
4271 if inMemory:
4272 cmdStr += "-i "
4273 cmdStr += numKeys + " " + value
4274 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004275 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004276 try:
4277 # TODO: Maybe make this less hardcoded
4278 # ConsistentMap Exceptions
4279 assert "org.onosproject.store.service" not in output
4280 # Node not leader
4281 assert "java.lang.IllegalStateException" not in output
4282 except AssertionError:
4283 main.log.error( "Error in processing '" + cmdStr + "' " +
4284 "command: " + str( output ) )
4285 return None
4286 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4287 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4288 results = {}
4289 for line in output.splitlines():
4290 new = re.search( newPattern, line )
4291 updated = re.search( updatedPattern, line )
4292 if new:
4293 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4294 elif updated:
4295 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004296 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004297 else:
4298 main.log.error( self.name + ": transactionlMapGet did not" +
4299 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004300 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4301 newPattern,
4302 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004303 main.log.debug( self.name + " actual: " + repr( output ) )
4304 return results
Jon Hallc6793552016-01-19 14:18:37 -08004305 except AssertionError:
4306 main.log.exception( "" )
4307 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004308 except TypeError:
4309 main.log.exception( self.name + ": Object not as expected" )
4310 return None
4311 except pexpect.EOF:
4312 main.log.error( self.name + ": EOF exception found" )
4313 main.log.error( self.name + ": " + self.handle.before )
4314 main.cleanup()
4315 main.exit()
4316 except Exception:
4317 main.log.exception( self.name + ": Uncaught exception!" )
4318 main.cleanup()
4319 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004320
acsmarsdaea66c2015-09-03 11:44:06 -07004321 def maps( self, jsonFormat=True ):
4322 """
4323 Description: Returns result of onos:maps
4324 Optional:
4325 * jsonFormat: enable json formatting of output
4326 """
4327 try:
4328 cmdStr = "maps"
4329 if jsonFormat:
4330 cmdStr += " -j"
4331 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004332 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004333 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004334 except AssertionError:
4335 main.log.exception( "" )
4336 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004337 except TypeError:
4338 main.log.exception( self.name + ": Object not as expected" )
4339 return None
4340 except pexpect.EOF:
4341 main.log.error( self.name + ": EOF exception found" )
4342 main.log.error( self.name + ": " + self.handle.before )
4343 main.cleanup()
4344 main.exit()
4345 except Exception:
4346 main.log.exception( self.name + ": Uncaught exception!" )
4347 main.cleanup()
4348 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004349
4350 def getSwController( self, uri, jsonFormat=True ):
4351 """
4352 Descrition: Gets the controller information from the device
4353 """
4354 try:
4355 cmd = "device-controllers "
4356 if jsonFormat:
4357 cmd += "-j "
4358 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004359 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004360 return response
Jon Hallc6793552016-01-19 14:18:37 -08004361 except AssertionError:
4362 main.log.exception( "" )
4363 return None
GlennRC050596c2015-11-18 17:06:41 -08004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return None
4367 except pexpect.EOF:
4368 main.log.error( self.name + ": EOF exception found" )
4369 main.log.error( self.name + ": " + self.handle.before )
4370 main.cleanup()
4371 main.exit()
4372 except Exception:
4373 main.log.exception( self.name + ": Uncaught exception!" )
4374 main.cleanup()
4375 main.exit()
4376
4377 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4378 """
4379 Descrition: sets the controller(s) for the specified device
4380
4381 Parameters:
4382 Required: uri - String: The uri of the device(switch).
4383 ip - String or List: The ip address of the controller.
4384 This parameter can be formed in a couple of different ways.
4385 VALID:
4386 10.0.0.1 - just the ip address
4387 tcp:10.0.0.1 - the protocol and the ip address
4388 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4389 so that you can add controllers with different
4390 protocols and ports
4391 INVALID:
4392 10.0.0.1:6653 - this is not supported by ONOS
4393
4394 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4395 port - The port number.
4396 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4397
4398 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4399 """
4400 try:
4401 cmd = "device-setcontrollers"
4402
4403 if jsonFormat:
4404 cmd += " -j"
4405 cmd += " " + uri
4406 if isinstance( ip, str ):
4407 ip = [ip]
4408 for item in ip:
4409 if ":" in item:
4410 sitem = item.split( ":" )
4411 if len(sitem) == 3:
4412 cmd += " " + item
4413 elif "." in sitem[1]:
4414 cmd += " {}:{}".format(item, port)
4415 else:
4416 main.log.error( "Malformed entry: " + item )
4417 raise TypeError
4418 else:
4419 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004420 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004421 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004422 if "Error" in response:
4423 main.log.error( response )
4424 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004425 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004426 except AssertionError:
4427 main.log.exception( "" )
4428 return None
GlennRC050596c2015-11-18 17:06:41 -08004429 except TypeError:
4430 main.log.exception( self.name + ": Object not as expected" )
4431 return main.FALSE
4432 except pexpect.EOF:
4433 main.log.error( self.name + ": EOF exception found" )
4434 main.log.error( self.name + ": " + self.handle.before )
4435 main.cleanup()
4436 main.exit()
4437 except Exception:
4438 main.log.exception( self.name + ": Uncaught exception!" )
4439 main.cleanup()
4440 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004441
4442 def removeDevice( self, device ):
4443 '''
4444 Description:
4445 Remove a device from ONOS by passing the uri of the device(s).
4446 Parameters:
4447 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4448 Returns:
4449 Returns main.FALSE if an exception is thrown or an error is present
4450 in the response. Otherwise, returns main.TRUE.
4451 NOTE:
4452 If a host cannot be removed, then this function will return main.FALSE
4453 '''
4454 try:
4455 if type( device ) is str:
4456 device = list( device )
4457
4458 for d in device:
4459 time.sleep( 1 )
4460 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004461 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004462 if "Error" in response:
4463 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4464 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004465 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004466 except AssertionError:
4467 main.log.exception( "" )
4468 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004469 except TypeError:
4470 main.log.exception( self.name + ": Object not as expected" )
4471 return main.FALSE
4472 except pexpect.EOF:
4473 main.log.error( self.name + ": EOF exception found" )
4474 main.log.error( self.name + ": " + self.handle.before )
4475 main.cleanup()
4476 main.exit()
4477 except Exception:
4478 main.log.exception( self.name + ": Uncaught exception!" )
4479 main.cleanup()
4480 main.exit()
4481
4482 def removeHost( self, host ):
4483 '''
4484 Description:
4485 Remove a host from ONOS by passing the id of the host(s)
4486 Parameters:
4487 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4488 Returns:
4489 Returns main.FALSE if an exception is thrown or an error is present
4490 in the response. Otherwise, returns main.TRUE.
4491 NOTE:
4492 If a host cannot be removed, then this function will return main.FALSE
4493 '''
4494 try:
4495 if type( host ) is str:
4496 host = list( host )
4497
4498 for h in host:
4499 time.sleep( 1 )
4500 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004501 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004502 if "Error" in response:
4503 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4504 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004505 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004506 except AssertionError:
4507 main.log.exception( "" )
4508 return None
GlennRC20fc6522015-12-23 23:26:57 -08004509 except TypeError:
4510 main.log.exception( self.name + ": Object not as expected" )
4511 return main.FALSE
4512 except pexpect.EOF:
4513 main.log.error( self.name + ": EOF exception found" )
4514 main.log.error( self.name + ": " + self.handle.before )
4515 main.cleanup()
4516 main.exit()
4517 except Exception:
4518 main.log.exception( self.name + ": Uncaught exception!" )
4519 main.cleanup()
4520 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004521
Jon Hallc6793552016-01-19 14:18:37 -08004522 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004523 '''
4524 Description:
4525 Bring link down or up in the null-provider.
4526 params:
4527 begin - (string) One end of a device or switch.
4528 end - (string) the other end of the device or switch
4529 returns:
4530 main.TRUE if no exceptions were thrown and no Errors are
4531 present in the resoponse. Otherwise, returns main.FALSE
4532 '''
4533 try:
Jon Hallc6793552016-01-19 14:18:37 -08004534 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004535 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004536 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004537 if "Error" in response or "Failure" in response:
4538 main.log.error( response )
4539 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004540 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004541 except AssertionError:
4542 main.log.exception( "" )
4543 return None
GlennRCed771242016-01-13 17:02:47 -08004544 except TypeError:
4545 main.log.exception( self.name + ": Object not as expected" )
4546 return main.FALSE
4547 except pexpect.EOF:
4548 main.log.error( self.name + ": EOF exception found" )
4549 main.log.error( self.name + ": " + self.handle.before )
4550 main.cleanup()
4551 main.exit()
4552 except Exception:
4553 main.log.exception( self.name + ": Uncaught exception!" )
4554 main.cleanup()
4555 main.exit()
4556