blob: fad5ce57f58a784a83f6ec0fe281070c6d1419f8 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1: # not in CLI
148 return main.TRUE
149 elif i == 3: # Timeout
150 return main.FALSE
151 else:
andrewonlab9627f432014-11-14 12:45:10 -0500152 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700158 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500159 main.cleanup()
160 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700161 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700162 main.log.error( self.name +
163 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 main.cleanup()
167 main.exit()
168
kelvin-onlabd3b64892015-01-20 13:26:24 -0800169 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab95ce8322014-10-13 14:12:04 -0400171 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800172
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800174 """
andrewonlab95ce8322014-10-13 14:12:04 -0400175 try:
176 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 main.cleanup()
179 main.exit()
180 else:
kelvin8ec71442015-01-15 16:57:00 -0800181 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800183 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400184 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800185 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800188 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800189 self.handle.sendline("")
190 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800191 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400195
196 return main.TRUE
197
Jon Halld4d4b372015-01-28 16:02:41 -0800198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400204 main.cleanup()
205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400208 main.cleanup()
209 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800210
pingping-lin57a56ce2015-05-20 16:43:48 -0700211 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800212 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
Jon Hallefbd9792015-03-05 16:11:36 -0800214 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800217 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800220
Hari Krishna25d42f72015-01-05 15:08:28 -0800221 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800223
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800226 """
You Wangf69ab392016-01-26 16:34:38 -0800227 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400228 try:
kelvin8ec71442015-01-15 16:57:00 -0800229 self.handle.sendline( "" )
230 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700231 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500232
233 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800234 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500235 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400236
kelvin8ec71442015-01-15 16:57:00 -0800237 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800239 i = self.handle.expect( [
240 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700241 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400242
243 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800245 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800246 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800247 "config:property-set -p org.apache.karaf.shell\
248 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800249 karafTimeout )
250 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400253 return main.TRUE
254 else:
kelvin8ec71442015-01-15 16:57:00 -0800255 # If failed, send ctrl+c to process and try again
256 main.log.info( "Starting CLI failed. Retrying..." )
257 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800259 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
260 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400261 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800263 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800264 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 "config:property-set -p org.apache.karaf.shell\
267 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800268 karafTimeout )
269 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800270 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800271 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400272 return main.TRUE
273 else:
kelvin8ec71442015-01-15 16:57:00 -0800274 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400276 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400277
Jon Halld4d4b372015-01-28 16:02:41 -0800278 except TypeError:
279 main.log.exception( self.name + ": Object not as expected" )
280 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400281 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800282 main.log.error( self.name + ": EOF exception found" )
283 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400284 main.cleanup()
285 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800286 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800287 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400288 main.cleanup()
289 main.exit()
290
Jon Hallefbd9792015-03-05 16:11:36 -0800291 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800292 """
293 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800294 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800295 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800296 Available level: DEBUG, TRACE, INFO, WARN, ERROR
297 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800298 """
299 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800300 lvlStr = ""
301 if level:
302 lvlStr = "--level=" + level
303
kelvin-onlab9f541032015-02-04 16:19:53 -0800304 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800305 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700306 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800307 main.log.error( self.name + ": onos cli session closed. ")
308 if self.onosIp:
309 main.log.warn( "Trying to reconnect " + self.onosIp )
310 reconnectResult = self.startOnosCli( self.onosIp )
311 if reconnectResult:
312 main.log.info( self.name + ": onos cli session reconnected." )
313 else:
314 main.log.error( self.name + ": reconnection failed." )
315 main.cleanup()
316 main.exit()
317 else:
318 main.cleanup()
319 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700320 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700321 self.handle.sendline( "" )
322 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800323 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700324 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800325 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800326
kelvin-onlab9f541032015-02-04 16:19:53 -0800327 response = self.handle.before
328 if re.search( "Error", response ):
329 return main.FALSE
330 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700331 except pexpect.TIMEOUT:
332 main.log.exception( self.name + ": TIMEOUT exception found" )
333 main.cleanup()
334 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800335 except pexpect.EOF:
336 main.log.error( self.name + ": EOF exception found" )
337 main.log.error( self.name + ": " + self.handle.before )
338 main.cleanup()
339 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800340 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800341 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400342 main.cleanup()
343 main.exit()
344
GlennRCed771242016-01-13 17:02:47 -0800345 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800346 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800347 Send a completely user specified string to
348 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400349 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800350
andrewonlaba18f6bf2014-10-13 19:31:54 -0400351 Warning: There are no sanity checking to commands
352 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800353
kelvin8ec71442015-01-15 16:57:00 -0800354 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400355 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800356 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
357 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800359 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800360 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800361 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800362 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
363 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700365 main.log.debug( self.name + ": Raw output" )
366 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700367
368 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800369 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800370 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700372 main.log.debug( self.name + ": ansiEscape output" )
373 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700374
kelvin-onlabfb521662015-02-27 09:52:40 -0800375 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800376 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700377 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700378 main.log.debug( self.name + ": Removed extra returns " +
379 "from output" )
380 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700381
382 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800383 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700384 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700385 main.log.debug( self.name + ": parsed and stripped output" )
386 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700387
Jon Hall63604932015-02-26 17:09:50 -0800388 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700389 output = response.split( cmdStr.strip(), 1 )
390 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700391 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700392 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700393 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800394 output = output[1].strip()
395 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800396 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800397 return output
GlennRCed771242016-01-13 17:02:47 -0800398 except pexpect.TIMEOUT:
399 main.log.error( self.name + ":ONOS timeout" )
400 if debug:
401 main.log.debug( self.handle.before )
402 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700403 except IndexError:
404 main.log.exception( self.name + ": Object not as expected" )
405 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400412 main.cleanup()
413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400416 main.cleanup()
417 main.exit()
418
kelvin8ec71442015-01-15 16:57:00 -0800419 # IMPORTANT NOTE:
420 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 # the cli command changing 'a:b' with 'aB'.
422 # Ex ) onos:topology > onosTopology
423 # onos:links > onosLinks
424 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800425
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800427 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400428 Adds a new cluster node by ID and address information.
429 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 * nodeId
431 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800434 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800436 cmdStr = "add-node " + str( nodeId ) + " " +\
437 str( ONOSIp ) + " " + str( tcpPort )
438 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800439 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800440 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( "Error in adding node" )
442 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800443 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800445 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800447 except AssertionError:
448 main.log.exception( "" )
449 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800450 except TypeError:
451 main.log.exception( self.name + ": Object not as expected" )
452 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( self.name + ": EOF exception found" )
455 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400456 main.cleanup()
457 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800459 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400460 main.cleanup()
461 main.exit()
462
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
andrewonlab86dc3082014-10-13 18:18:38 -0400465 Removes a cluster by ID
466 Issues command: 'remove-node [<node-id>]'
467 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800469 """
andrewonlab86dc3082014-10-13 18:18:38 -0400470 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400471
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700473 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800474 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700475 if re.search( "Error", handle ):
476 main.log.error( "Error in removing node" )
477 main.log.error( handle )
478 return main.FALSE
479 else:
480 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800481 except AssertionError:
482 main.log.exception( "" )
483 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800484 except TypeError:
485 main.log.exception( self.name + ": Object not as expected" )
486 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400487 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800488 main.log.error( self.name + ": EOF exception found" )
489 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400490 main.cleanup()
491 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800493 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400494 main.cleanup()
495 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400496
Jon Hall61282e32015-03-19 11:34:11 -0700497 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800498 """
andrewonlab7c211572014-10-15 16:45:20 -0400499 List the nodes currently visible
500 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700501 Optional argument:
502 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlab7c211572014-10-15 16:45:20 -0400504 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700506 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 cmdStr += " -j"
508 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800509 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700510 return output
Jon Hallc6793552016-01-19 14:18:37 -0800511 except AssertionError:
512 main.log.exception( "" )
513 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800514 except TypeError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
andrewonlab7c211572014-10-15 16:45:20 -0400517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400520 main.cleanup()
521 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800522 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800523 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400524 main.cleanup()
525 main.exit()
526
kelvin8ec71442015-01-15 16:57:00 -0800527 def topology( self ):
528 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700529 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700530 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700531 Return:
532 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800533 """
andrewonlab95ce8322014-10-13 14:12:04 -0400534 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700535 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800537 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400539 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800540 except AssertionError:
541 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800542 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800543 except TypeError:
544 main.log.exception( self.name + ": Object not as expected" )
545 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400546 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 main.cleanup()
550 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800551 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800552 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 main.cleanup()
554 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800555
jenkins7ead5a82015-03-13 10:28:21 -0700556 def deviceRemove( self, deviceId ):
557 """
558 Removes particular device from storage
559
560 TODO: refactor this function
561 """
562 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700563 cmdStr = "device-remove " + str( deviceId )
564 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 if re.search( "Error", handle ):
567 main.log.error( "Error in removing device" )
568 main.log.error( handle )
569 return main.FALSE
570 else:
571 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800572 except AssertionError:
573 main.log.exception( "" )
574 return None
jenkins7ead5a82015-03-13 10:28:21 -0700575 except TypeError:
576 main.log.exception( self.name + ": Object not as expected" )
577 return None
578 except pexpect.EOF:
579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
581 main.cleanup()
582 main.exit()
583 except Exception:
584 main.log.exception( self.name + ": Uncaught exception!" )
585 main.cleanup()
586 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700587
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800589 """
Jon Hall7b02d952014-10-17 20:14:54 -0400590 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800593 """
andrewonlab86dc3082014-10-13 18:18:38 -0400594 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 cmdStr += " -j"
598 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800599 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700600 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800601 except AssertionError:
602 main.log.exception( "" )
603 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800604 except TypeError:
605 main.log.exception( self.name + ": Object not as expected" )
606 return None
andrewonlab7c211572014-10-15 16:45:20 -0400607 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800608 main.log.error( self.name + ": EOF exception found" )
609 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400610 main.cleanup()
611 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800612 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800613 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800619 This balances the devices across all controllers
620 by issuing command: 'onos> onos:balance-masters'
621 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800623 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700625 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800626 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 if re.search( "Error", handle ):
628 main.log.error( "Error in balancing masters" )
629 main.log.error( handle )
630 return main.FALSE
631 else:
632 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800633 except AssertionError:
634 main.log.exception( "" )
635 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 main.cleanup()
647 main.exit()
648
Jon Hallc6793552016-01-19 14:18:37 -0800649 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700650 """
651 Returns the output of the masters command.
652 Optional argument:
653 * jsonFormat - boolean indicating if you want output in json
654 """
655 try:
656 cmdStr = "onos:masters"
657 if jsonFormat:
658 cmdStr += " -j"
659 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800660 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700661 return output
Jon Hallc6793552016-01-19 14:18:37 -0800662 except AssertionError:
663 main.log.exception( "" )
664 return None
acsmars24950022015-07-30 18:00:43 -0700665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
668 except pexpect.EOF:
669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
671 main.cleanup()
672 main.exit()
673 except Exception:
674 main.log.exception( self.name + ": Uncaught exception!" )
675 main.cleanup()
676 main.exit()
677
Jon Hallc6793552016-01-19 14:18:37 -0800678 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700679 """
680 Uses the master command to check that the devices' leadership
681 is evenly divided
682
683 Dependencies: checkMasters() and summary()
684
685 Returns main.True if the devices are balanced
686 Returns main.False if the devices are unbalanced
687 Exits on Exception
688 Returns None on TypeError
689 """
690 try:
Jon Hallc6793552016-01-19 14:18:37 -0800691 summaryOutput = self.summary()
692 totalDevices = json.loads( summaryOutput )[ "devices" ]
693 except ( TypeError, ValueError ):
694 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
695 return None
696 try:
acsmars24950022015-07-30 18:00:43 -0700697 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800698 mastersOutput = self.checkMasters()
699 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700700 first = masters[ 0 ][ "size" ]
701 for master in masters:
702 totalOwnedDevices += master[ "size" ]
703 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
704 main.log.error( "Mastership not balanced" )
705 main.log.info( "\n" + self.checkMasters( False ) )
706 return main.FALSE
707 main.log.info( "Mastership balanced between " \
708 + str( len(masters) ) + " masters" )
709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800710 except ( TypeError, ValueError ):
711 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700712 return None
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
716 main.cleanup()
717 main.exit()
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
720 main.cleanup()
721 main.exit()
722
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800724 """
Jon Halle8217482014-10-17 13:49:14 -0400725 Lists all core links
726 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800728 """
Jon Halle8217482014-10-17 13:49:14 -0400729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 cmdStr += " -j"
733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800736 except AssertionError:
737 main.log.exception( "" )
738 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800739 except TypeError:
740 main.log.exception( self.name + ": Object not as expected" )
741 return None
Jon Halle8217482014-10-17 13:49:14 -0400742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800743 main.log.error( self.name + ": EOF exception found" )
744 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400745 main.cleanup()
746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800748 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Jon Halle8217482014-10-17 13:49:14 -0400754 Lists all ports
755 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Jon Halle8217482014-10-17 13:49:14 -0400758 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700759 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700761 cmdStr += " -j"
762 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800763 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700764 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800765 except AssertionError:
766 main.log.exception( "" )
767 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800768 except TypeError:
769 main.log.exception( self.name + ": Object not as expected" )
770 return None
Jon Halle8217482014-10-17 13:49:14 -0400771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400774 main.cleanup()
775 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800776 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800777 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400778 main.cleanup()
779 main.exit()
780
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800782 """
Jon Hall983a1702014-10-28 18:44:22 -0400783 Lists all devices and the controllers with roles assigned to them
784 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800786 """
andrewonlab7c211572014-10-15 16:45:20 -0400787 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700788 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700790 cmdStr += " -j"
791 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800792 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800794 except AssertionError:
795 main.log.exception( "" )
796 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800797 except TypeError:
798 main.log.exception( self.name + ": Object not as expected" )
799 return None
Jon Hall983a1702014-10-28 18:44:22 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400803 main.cleanup()
804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800805 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800806 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400807 main.cleanup()
808 main.exit()
809
kelvin-onlabd3b64892015-01-20 13:26:24 -0800810 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800811 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800812 Given the a string containing the json representation of the "roles"
813 cli command and a partial or whole device id, returns a json object
814 containing the roles output for the first device whose id contains
815 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400816
817 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800818 A dict of the role assignments for the given device or
819 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800820 """
Jon Hall983a1702014-10-28 18:44:22 -0400821 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400823 return None
824 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 rawRoles = self.roles()
826 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800827 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800829 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800830 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400831 return device
832 return None
Jon Hallc6793552016-01-19 14:18:37 -0800833 except ( TypeError, ValueError ):
834 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800835 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400839 main.cleanup()
840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800842 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400843 main.cleanup()
844 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800845
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Hall94fd0472014-12-08 11:52:42 -0800848 Iterates through each device and checks if there is a master assigned
849 Returns: main.TRUE if each device has a master
850 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall94fd0472014-12-08 11:52:42 -0800852 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 rawRoles = self.roles()
854 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800855 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800857 # print device
858 if device[ 'master' ] == "none":
859 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800860 return main.FALSE
861 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800862 except ( TypeError, ValueError ):
863 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800864 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800868 main.cleanup()
869 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800870 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800871 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800872 main.cleanup()
873 main.exit()
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400877 Returns string of paths, and the cost.
878 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800879 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400880 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
882 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800883 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800884 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800885 main.log.error( "Error in getting paths" )
886 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400887 else:
kelvin8ec71442015-01-15 16:57:00 -0800888 path = handle.split( ";" )[ 0 ]
889 cost = handle.split( ";" )[ 1 ]
890 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800891 except AssertionError:
892 main.log.exception( "" )
893 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800894 except TypeError:
895 main.log.exception( self.name + ": Object not as expected" )
896 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( self.name + ": EOF exception found" )
899 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400900 main.cleanup()
901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400904 main.cleanup()
905 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Hallffb386d2014-11-21 13:43:38 -0800909 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400910 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800912 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400913 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700914 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 cmdStr += " -j"
917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800918 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800919 try:
920 # TODO: Maybe make this less hardcoded
921 # ConsistentMap Exceptions
922 assert "org.onosproject.store.service" not in handle
923 # Node not leader
924 assert "java.lang.IllegalStateException" not in handle
925 except AssertionError:
926 main.log.error( "Error in processing '" + cmdStr + "' " +
927 "command: " + str( handle ) )
928 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400939 main.cleanup()
940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400943 main.cleanup()
944 main.exit()
945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800947 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400948 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800949
Jon Hallefbd9792015-03-05 16:11:36 -0800950 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800951 partial mac address
952
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800954 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400955 try:
kelvin8ec71442015-01-15 16:57:00 -0800956 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400957 return None
958 else:
959 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 rawHosts = self.hosts()
961 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800962 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800964 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800965 if not host:
966 pass
967 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400968 return host
969 return None
Jon Hallc6793552016-01-19 14:18:37 -0800970 except ( TypeError, ValueError ):
971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800972 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400973 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400976 main.cleanup()
977 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800979 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400980 main.cleanup()
981 main.exit()
982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800984 """
985 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400986 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800987
andrewonlab3f0a4af2014-10-17 12:25:14 -0400988 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400990 IMPORTANT:
991 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800992 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400993 Furthermore, it assumes that value of VLAN is '-1'
994 Description:
kelvin8ec71442015-01-15 16:57:00 -0800995 Converts mininet hosts ( h1, h2, h3... ) into
996 ONOS format ( 00:00:00:00:00:01/-1 , ... )
997 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001002 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 hostHex = hex( int( host ) ).zfill( 12 )
1004 hostHex = str( hostHex ).replace( 'x', '0' )
1005 i = iter( str( hostHex ) )
1006 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1007 hostHex = hostHex + "/-1"
1008 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001009
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001011
Jon Halld4d4b372015-01-28 16:02:41 -08001012 except TypeError:
1013 main.log.exception( self.name + ": Object not as expected" )
1014 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001015 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001018 main.cleanup()
1019 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001020 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001021 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001022 main.cleanup()
1023 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001024
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001026 """
andrewonlabe6745342014-10-17 14:29:13 -04001027 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 * hostIdOne: ONOS host id for host1
1029 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001030 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001031 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001032 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001033 Returns:
1034 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlabe6745342014-10-17 14:29:13 -04001036 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1038 " " + str( hostIdTwo )
1039 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001040 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001041 if re.search( "Error", handle ):
1042 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001043 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001044 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001045 else:
1046 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001047 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1048 match = re.search('id=0x([\da-f]+),', handle)
1049 if match:
1050 return match.group()[3:-1]
1051 else:
1052 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001053 main.log.debug( "Response from ONOS was: " +
1054 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001055 return None
Jon Hallc6793552016-01-19 14:18:37 -08001056 except AssertionError:
1057 main.log.exception( "" )
1058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
andrewonlabe6745342014-10-17 14:29:13 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab7b31d232014-10-24 13:31:47 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001077 Optional:
1078 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001079 Description:
1080 Adds an optical intent by specifying an ingress and egress device
1081 Returns:
1082 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001083 """
andrewonlab7b31d232014-10-24 13:31:47 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1086 " " + str( egressDevice )
1087 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001088 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001089 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 main.log.error( "Error in adding Optical intent" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001094 main.log.info( "Optical intent installed between " +
1095 str( ingressDevice ) + " and " +
1096 str( egressDevice ) )
1097 match = re.search('id=0x([\da-f]+),', handle)
1098 if match:
1099 return match.group()[3:-1]
1100 else:
1101 main.log.error( "Error, intent ID not found" )
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except AssertionError:
1104 main.log.exception( "" )
1105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001106 except TypeError:
1107 main.log.exception( self.name + ": Object not as expected" )
1108 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( self.name + ": EOF exception found" )
1111 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001112 main.cleanup()
1113 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001114 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001115 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001116 main.cleanup()
1117 main.exit()
1118
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001120 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 ingressDevice,
1122 egressDevice,
1123 portIngress="",
1124 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001125 ethType="",
1126 ethSrc="",
1127 ethDst="",
1128 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001130 ipProto="",
1131 ipSrc="",
1132 ipDst="",
1133 tcpSrc="",
1134 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001136 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 * ingressDevice: device id of ingress device
1138 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001139 Optional:
1140 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001141 * ethSrc: specify ethSrc ( i.e. src mac addr )
1142 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001143 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001145 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001146 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001147 * ipSrc: specify ip source address
1148 * ipDst: specify ip destination address
1149 * tcpSrc: specify tcp source port
1150 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001151 Description:
kelvin8ec71442015-01-15 16:57:00 -08001152 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001153 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001154 Returns:
1155 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001156
Jon Halle3f39ff2015-01-13 11:50:53 -08001157 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001158 options developers provide for point-to-point
1159 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001161 try:
kelvin8ec71442015-01-15 16:57:00 -08001162 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001163 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001165 and not ipProto and not ipSrc and not ipDst \
1166 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001167 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001168
andrewonlab289e4b72014-10-21 21:24:18 -04001169 else:
andrewonlab36af3822014-11-18 17:48:18 -05001170 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001171
andrewonlab0c0a6772014-10-22 12:31:18 -04001172 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001173 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001174 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --ethSrc " + str( ethSrc )
1176 if ethDst:
1177 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001178 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 cmd += " --lambda "
1182 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001184 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001186 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001188 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001190 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001191 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001192
kelvin8ec71442015-01-15 16:57:00 -08001193 # Check whether the user appended the port
1194 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if "/" in ingressDevice:
1196 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001197 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001199 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001200 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001201 # Would it make sense to throw an exception and exit
1202 # the test?
1203 return None
andrewonlab36af3822014-11-18 17:48:18 -05001204
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 str( ingressDevice ) + "/" +\
1207 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001208
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if "/" in egressDevice:
1210 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001211 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001213 main.log.error( "You must specify the egress port" )
1214 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001215
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001217 str( egressDevice ) + "/" +\
1218 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001219
kelvin-onlab898a6c62015-01-16 14:13:53 -08001220 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001222 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001225 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 # TODO: print out all the options in this message?
1228 main.log.info( "Point-to-point intent installed between " +
1229 str( ingressDevice ) + " and " +
1230 str( egressDevice ) )
1231 match = re.search('id=0x([\da-f]+),', handle)
1232 if match:
1233 return match.group()[3:-1]
1234 else:
1235 main.log.error( "Error, intent ID not found" )
1236 return None
Jon Hallc6793552016-01-19 14:18:37 -08001237 except AssertionError:
1238 main.log.exception( "" )
1239 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001240 except TypeError:
1241 main.log.exception( self.name + ": Object not as expected" )
1242 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.error( self.name + ": EOF exception found" )
1245 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001246 main.cleanup()
1247 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001248 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001249 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001250 main.cleanup()
1251 main.exit()
1252
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001254 self,
shahshreyac2f97072015-03-19 17:04:29 -07001255 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001257 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 ethType="",
1260 ethSrc="",
1261 ethDst="",
1262 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 ipProto="",
1265 ipSrc="",
1266 ipDst="",
1267 tcpSrc="",
1268 tcpDst="",
1269 setEthSrc="",
1270 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001271 """
shahshreyad0c80432014-12-04 16:56:05 -08001272 Note:
shahshreya70622b12015-03-19 17:19:00 -07001273 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001274 is same. That is, all ingress devices include port numbers
1275 with a "/" or all ingress devices could specify device
1276 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001277 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001278 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001279 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
1293 * setEthSrc: action to Rewrite Source MAC Address
1294 * setEthDst: action to Rewrite Destination MAC Address
1295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001302 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
shahshreyad0c80432014-12-04 16:56:05 -08001305 try:
kelvin8ec71442015-01-15 16:57:00 -08001306 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001307 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001309 and not ipProto and not ipSrc and not ipDst\
1310 and not tcpSrc and not tcpDst and not setEthSrc\
1311 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001312 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001313
1314 else:
1315 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001316
shahshreyad0c80432014-12-04 16:56:05 -08001317 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001318 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001319 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001320 cmd += " --ethSrc " + str( ethSrc )
1321 if ethDst:
1322 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001323 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001324 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001326 cmd += " --lambda "
1327 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001329 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001330 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001331 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001333 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001334 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001335 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001336 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001337 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001339 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001341
kelvin8ec71442015-01-15 16:57:00 -08001342 # Check whether the user appended the port
1343 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001344
1345 if portIngressList is None:
1346 for ingressDevice in ingressDeviceList:
1347 if "/" in ingressDevice:
1348 cmd += " " + str( ingressDevice )
1349 else:
1350 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001351 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001352 # TODO: perhaps more meaningful return
1353 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001354 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001355 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001356 for ingressDevice, portIngress in zip( ingressDeviceList,
1357 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001358 cmd += " " + \
1359 str( ingressDevice ) + "/" +\
1360 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001361 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001362 main.log.error( "Device list and port list does not " +
1363 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001364 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if "/" in egressDevice:
1366 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001367 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.error( "You must specify " +
1370 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001371 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001372
kelvin8ec71442015-01-15 16:57:00 -08001373 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 str( egressDevice ) + "/" +\
1375 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001377 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001379 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 main.log.error( "Error in adding multipoint-to-singlepoint " +
1381 "intent" )
1382 return None
shahshreyad0c80432014-12-04 16:56:05 -08001383 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001384 match = re.search('id=0x([\da-f]+),', handle)
1385 if match:
1386 return match.group()[3:-1]
1387 else:
1388 main.log.error( "Error, intent ID not found" )
1389 return None
Jon Hallc6793552016-01-19 14:18:37 -08001390 except AssertionError:
1391 main.log.exception( "" )
1392 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001393 except TypeError:
1394 main.log.exception( self.name + ": Object not as expected" )
1395 return None
1396 except pexpect.EOF:
1397 main.log.error( self.name + ": EOF exception found" )
1398 main.log.error( self.name + ": " + self.handle.before )
1399 main.cleanup()
1400 main.exit()
1401 except Exception:
1402 main.log.exception( self.name + ": Uncaught exception!" )
1403 main.cleanup()
1404 main.exit()
1405
1406 def addSinglepointToMultipointIntent(
1407 self,
1408 ingressDevice,
1409 egressDeviceList,
1410 portIngress="",
1411 portEgressList=None,
1412 ethType="",
1413 ethSrc="",
1414 ethDst="",
1415 bandwidth="",
1416 lambdaAlloc=False,
1417 ipProto="",
1418 ipSrc="",
1419 ipDst="",
1420 tcpSrc="",
1421 tcpDst="",
1422 setEthSrc="",
1423 setEthDst="" ):
1424 """
1425 Note:
1426 This function assumes the format of all egress devices
1427 is same. That is, all egress devices include port numbers
1428 with a "/" or all egress devices could specify device
1429 ids and port numbers seperately.
1430 Required:
1431 * EgressDeviceList: List of device ids of egress device
1432 ( Atleast 2 eress devices required in the list )
1433 * ingressDevice: device id of ingress device
1434 Optional:
1435 * ethType: specify ethType
1436 * ethSrc: specify ethSrc ( i.e. src mac addr )
1437 * ethDst: specify ethDst ( i.e. dst mac addr )
1438 * bandwidth: specify bandwidth capacity of link
1439 * lambdaAlloc: if True, intent will allocate lambda
1440 for the specified intent
1441 * ipProto: specify ip protocol
1442 * ipSrc: specify ip source address
1443 * ipDst: specify ip destination address
1444 * tcpSrc: specify tcp source port
1445 * tcpDst: specify tcp destination port
1446 * setEthSrc: action to Rewrite Source MAC Address
1447 * setEthDst: action to Rewrite Destination MAC Address
1448 Description:
1449 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1450 specifying device id's and optional fields
1451 Returns:
1452 A string of the intent id or None on error
1453
1454 NOTE: This function may change depending on the
1455 options developers provide for singlepoint-to-multipoint
1456 intent via cli
1457 """
1458 try:
1459 # If there are no optional arguments
1460 if not ethType and not ethSrc and not ethDst\
1461 and not bandwidth and not lambdaAlloc\
1462 and not ipProto and not ipSrc and not ipDst\
1463 and not tcpSrc and not tcpDst and not setEthSrc\
1464 and not setEthDst:
1465 cmd = "add-single-to-multi-intent"
1466
1467 else:
1468 cmd = "add-single-to-multi-intent"
1469
1470 if ethType:
1471 cmd += " --ethType " + str( ethType )
1472 if ethSrc:
1473 cmd += " --ethSrc " + str( ethSrc )
1474 if ethDst:
1475 cmd += " --ethDst " + str( ethDst )
1476 if bandwidth:
1477 cmd += " --bandwidth " + str( bandwidth )
1478 if lambdaAlloc:
1479 cmd += " --lambda "
1480 if ipProto:
1481 cmd += " --ipProto " + str( ipProto )
1482 if ipSrc:
1483 cmd += " --ipSrc " + str( ipSrc )
1484 if ipDst:
1485 cmd += " --ipDst " + str( ipDst )
1486 if tcpSrc:
1487 cmd += " --tcpSrc " + str( tcpSrc )
1488 if tcpDst:
1489 cmd += " --tcpDst " + str( tcpDst )
1490 if setEthSrc:
1491 cmd += " --setEthSrc " + str( setEthSrc )
1492 if setEthDst:
1493 cmd += " --setEthDst " + str( setEthDst )
1494
1495 # Check whether the user appended the port
1496 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001497
kelvin-onlabb9408212015-04-01 13:34:04 -07001498 if "/" in ingressDevice:
1499 cmd += " " + str( ingressDevice )
1500 else:
1501 if not portIngress:
1502 main.log.error( "You must specify " +
1503 "the Ingress port" )
1504 return main.FALSE
1505
1506 cmd += " " +\
1507 str( ingressDevice ) + "/" +\
1508 str( portIngress )
1509
1510 if portEgressList is None:
1511 for egressDevice in egressDeviceList:
1512 if "/" in egressDevice:
1513 cmd += " " + str( egressDevice )
1514 else:
1515 main.log.error( "You must specify " +
1516 "the egress port" )
1517 # TODO: perhaps more meaningful return
1518 return main.FALSE
1519 else:
1520 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001521 for egressDevice, portEgress in zip( egressDeviceList,
1522 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001523 cmd += " " + \
1524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001526 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001527 main.log.error( "Device list and port list does not " +
1528 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001529 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001530 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001531 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001532 # If error, return error message
1533 if re.search( "Error", handle ):
1534 main.log.error( "Error in adding singlepoint-to-multipoint " +
1535 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001536 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001537 else:
1538 match = re.search('id=0x([\da-f]+),', handle)
1539 if match:
1540 return match.group()[3:-1]
1541 else:
1542 main.log.error( "Error, intent ID not found" )
1543 return None
Jon Hallc6793552016-01-19 14:18:37 -08001544 except AssertionError:
1545 main.log.exception( "" )
1546 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001547 except TypeError:
1548 main.log.exception( self.name + ": Object not as expected" )
1549 return None
shahshreyad0c80432014-12-04 16:56:05 -08001550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001551 main.log.error( self.name + ": EOF exception found" )
1552 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001553 main.cleanup()
1554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001556 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001557 main.cleanup()
1558 main.exit()
1559
Hari Krishna9e232602015-04-13 17:29:08 -07001560 def addMplsIntent(
1561 self,
1562 ingressDevice,
1563 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001564 ingressPort="",
1565 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001566 ethType="",
1567 ethSrc="",
1568 ethDst="",
1569 bandwidth="",
1570 lambdaAlloc=False,
1571 ipProto="",
1572 ipSrc="",
1573 ipDst="",
1574 tcpSrc="",
1575 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001576 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001577 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001578 priority=""):
1579 """
1580 Required:
1581 * ingressDevice: device id of ingress device
1582 * egressDevice: device id of egress device
1583 Optional:
1584 * ethType: specify ethType
1585 * ethSrc: specify ethSrc ( i.e. src mac addr )
1586 * ethDst: specify ethDst ( i.e. dst mac addr )
1587 * bandwidth: specify bandwidth capacity of link
1588 * lambdaAlloc: if True, intent will allocate lambda
1589 for the specified intent
1590 * ipProto: specify ip protocol
1591 * ipSrc: specify ip source address
1592 * ipDst: specify ip destination address
1593 * tcpSrc: specify tcp source port
1594 * tcpDst: specify tcp destination port
1595 * ingressLabel: Ingress MPLS label
1596 * egressLabel: Egress MPLS label
1597 Description:
1598 Adds MPLS intent by
1599 specifying device id's and optional fields
1600 Returns:
1601 A string of the intent id or None on error
1602
1603 NOTE: This function may change depending on the
1604 options developers provide for MPLS
1605 intent via cli
1606 """
1607 try:
1608 # If there are no optional arguments
1609 if not ethType and not ethSrc and not ethDst\
1610 and not bandwidth and not lambdaAlloc \
1611 and not ipProto and not ipSrc and not ipDst \
1612 and not tcpSrc and not tcpDst and not ingressLabel \
1613 and not egressLabel:
1614 cmd = "add-mpls-intent"
1615
1616 else:
1617 cmd = "add-mpls-intent"
1618
1619 if ethType:
1620 cmd += " --ethType " + str( ethType )
1621 if ethSrc:
1622 cmd += " --ethSrc " + str( ethSrc )
1623 if ethDst:
1624 cmd += " --ethDst " + str( ethDst )
1625 if bandwidth:
1626 cmd += " --bandwidth " + str( bandwidth )
1627 if lambdaAlloc:
1628 cmd += " --lambda "
1629 if ipProto:
1630 cmd += " --ipProto " + str( ipProto )
1631 if ipSrc:
1632 cmd += " --ipSrc " + str( ipSrc )
1633 if ipDst:
1634 cmd += " --ipDst " + str( ipDst )
1635 if tcpSrc:
1636 cmd += " --tcpSrc " + str( tcpSrc )
1637 if tcpDst:
1638 cmd += " --tcpDst " + str( tcpDst )
1639 if ingressLabel:
1640 cmd += " --ingressLabel " + str( ingressLabel )
1641 if egressLabel:
1642 cmd += " --egressLabel " + str( egressLabel )
1643 if priority:
1644 cmd += " --priority " + str( priority )
1645
1646 # Check whether the user appended the port
1647 # or provided it as an input
1648 if "/" in ingressDevice:
1649 cmd += " " + str( ingressDevice )
1650 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001651 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001652 main.log.error( "You must specify the ingress port" )
1653 return None
1654
1655 cmd += " " + \
1656 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001657 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001658
1659 if "/" in egressDevice:
1660 cmd += " " + str( egressDevice )
1661 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001662 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001663 main.log.error( "You must specify the egress port" )
1664 return None
1665
1666 cmd += " " +\
1667 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001668 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001669
1670 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001671 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001672 # If error, return error message
1673 if re.search( "Error", handle ):
1674 main.log.error( "Error in adding mpls intent" )
1675 return None
1676 else:
1677 # TODO: print out all the options in this message?
1678 main.log.info( "MPLS intent installed between " +
1679 str( ingressDevice ) + " and " +
1680 str( egressDevice ) )
1681 match = re.search('id=0x([\da-f]+),', handle)
1682 if match:
1683 return match.group()[3:-1]
1684 else:
1685 main.log.error( "Error, intent ID not found" )
1686 return None
Jon Hallc6793552016-01-19 14:18:37 -08001687 except AssertionError:
1688 main.log.exception( "" )
1689 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001690 except TypeError:
1691 main.log.exception( self.name + ": Object not as expected" )
1692 return None
1693 except pexpect.EOF:
1694 main.log.error( self.name + ": EOF exception found" )
1695 main.log.error( self.name + ": " + self.handle.before )
1696 main.cleanup()
1697 main.exit()
1698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
1700 main.cleanup()
1701 main.exit()
1702
Jon Hallefbd9792015-03-05 16:11:36 -08001703 def removeIntent( self, intentId, app='org.onosproject.cli',
1704 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001705 """
shahshreya1c818fc2015-02-26 13:44:08 -08001706 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001707 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001708 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001709 -p or --purge: Purge the intent from the store after removal
1710
Jon Halle3f39ff2015-01-13 11:50:53 -08001711 Returns:
1712 main.False on error and
1713 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001714 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001715 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001716 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001717 if purge:
1718 cmdStr += " -p"
1719 if sync:
1720 cmdStr += " -s"
1721
1722 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001724 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001725 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001726 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001727 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001728 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001729 # TODO: Should this be main.TRUE
1730 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001731 except AssertionError:
1732 main.log.exception( "" )
1733 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001734 except TypeError:
1735 main.log.exception( self.name + ": Object not as expected" )
1736 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001738 main.log.error( self.name + ": EOF exception found" )
1739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001740 main.cleanup()
1741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001744 main.cleanup()
1745 main.exit()
1746
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001747 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001748 """
1749 Purges all WITHDRAWN Intents
1750 """
1751 try:
1752 cmdStr = "purge-intents"
1753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001754 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001755 if re.search( "Error", handle ):
1756 main.log.error( "Error in purging intents" )
1757 return main.FALSE
1758 else:
1759 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001760 except AssertionError:
1761 main.log.exception( "" )
1762 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
1766 except pexpect.EOF:
1767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
1769 main.cleanup()
1770 main.exit()
1771 except Exception:
1772 main.log.exception( self.name + ": Uncaught exception!" )
1773 main.cleanup()
1774 main.exit()
1775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001777 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 NOTE: This method should be used after installing application:
1779 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001780 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001782 Description:
1783 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001784 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001785 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001786 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001788 cmdStr += " -j"
1789 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001790 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001791 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001792 except AssertionError:
1793 main.log.exception( "" )
1794 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001795 except TypeError:
1796 main.log.exception( self.name + ": Object not as expected" )
1797 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001798 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001799 main.log.error( self.name + ": EOF exception found" )
1800 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001801 main.cleanup()
1802 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001804 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001805 main.cleanup()
1806 main.exit()
1807
pingping-lin54b03372015-08-13 14:43:10 -07001808 def ipv4RouteNumber( self ):
1809 """
1810 NOTE: This method should be used after installing application:
1811 onos-app-sdnip
1812 Description:
1813 Obtain the total IPv4 routes number in the system
1814 """
1815 try:
1816 cmdStr = "routes -s -j"
1817 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001818 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001819 jsonResult = json.loads( handle )
1820 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001821 except AssertionError:
1822 main.log.exception( "" )
1823 return None
1824 except ( TypeError, ValueError ):
1825 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001826 return None
1827 except pexpect.EOF:
1828 main.log.error( self.name + ": EOF exception found" )
1829 main.log.error( self.name + ": " + self.handle.before )
1830 main.cleanup()
1831 main.exit()
1832 except Exception:
1833 main.log.exception( self.name + ": Uncaught exception!" )
1834 main.cleanup()
1835 main.exit()
1836
pingping-lin8244a3b2015-09-16 13:36:56 -07001837 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001838 """
andrewonlabe6745342014-10-17 14:29:13 -04001839 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001840 Obtain intents from the ONOS cli.
1841 Optional:
1842 * jsonFormat: Enable output formatting in json, default to True
1843 * summary: Whether only output the intent summary, defaults to False
1844 * type: Only output a certain type of intent. This options is valid
1845 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 """
andrewonlabe6745342014-10-17 14:29:13 -04001847 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001848 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001849 if summary:
1850 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001852 cmdStr += " -j"
1853 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001854 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001855 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001856 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001857 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001858 else:
Jon Hallff566d52016-01-15 14:45:36 -08001859 intentType = ""
1860 # IF we want the summary of a specific intent type
1861 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001862 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001863 if intentType in jsonResult.keys():
1864 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001865 else:
Jon Hallff566d52016-01-15 14:45:36 -08001866 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001867 return handle
1868 else:
1869 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001870 except AssertionError:
1871 main.log.exception( "" )
1872 return None
1873 except ( TypeError, ValueError ):
1874 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001875 return None
1876 except pexpect.EOF:
1877 main.log.error( self.name + ": EOF exception found" )
1878 main.log.error( self.name + ": " + self.handle.before )
1879 main.cleanup()
1880 main.exit()
1881 except Exception:
1882 main.log.exception( self.name + ": Uncaught exception!" )
1883 main.cleanup()
1884 main.exit()
1885
kelvin-onlab54400a92015-02-26 18:05:51 -08001886 def getIntentState(self, intentsId, intentsJson=None):
1887 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001888 Check intent state.
1889 Accepts a single intent ID (string type) or a list of intent IDs.
1890 Returns the state(string type) of the id if a single intent ID is
1891 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001892 Returns a dictionary with intent IDs as the key and its
1893 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001894 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001895 intentId: intent ID (string type)
1896 intentsJson: parsed json object from the onos:intents api
1897 Returns:
1898 state = An intent's state- INSTALL,WITHDRAWN etc.
1899 stateDict = Dictionary of intent's state. intent ID as the keys and
1900 state as the values.
1901 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001902 try:
1903 state = "State is Undefined"
1904 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001905 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001906 else:
Jon Hallc6793552016-01-19 14:18:37 -08001907 rawJson = intentsJson
1908 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001909 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001910 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001911 if intentsId == intent[ 'id' ]:
1912 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001913 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001914 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1915 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001916 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001917 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001918 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001919 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001920 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001921 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001922 if intentsId[ i ] == intents[ 'id' ]:
1923 stateDict[ 'state' ] = intents[ 'state' ]
1924 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001925 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001926 break
Jon Hallefbd9792015-03-05 16:11:36 -08001927 if len( intentsId ) != len( dictList ):
1928 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001929 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001930 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001931 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001932 return None
Jon Hallc6793552016-01-19 14:18:37 -08001933 except ( TypeError, ValueError ):
1934 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001935 return None
1936 except pexpect.EOF:
1937 main.log.error( self.name + ": EOF exception found" )
1938 main.log.error( self.name + ": " + self.handle.before )
1939 main.cleanup()
1940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001941 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001942 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001943 main.cleanup()
1944 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001945
kelvin-onlabf512e942015-06-08 19:42:59 -07001946 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001947 """
1948 Description:
1949 Check intents state
1950 Required:
1951 intentsId - List of intents ID to be checked
1952 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001953 expectedState - Check the expected state(s) of each intents
1954 state in the list.
1955 *NOTE: You can pass in a list of expected state,
1956 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001957 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001958 Returns main.TRUE only if all intent are the same as expected states
1959 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001960 """
1961 try:
1962 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001963 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001964 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001965 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08001966 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001967 "getting intents state" )
1968 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001969
1970 if isinstance( expectedState, types.StringType ):
1971 for intents in intentsDict:
1972 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001973 main.log.debug( self.name + " : Intent ID - " +
1974 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001975 " actual state = " +
1976 intents.get( 'state' )
1977 + " does not equal expected state = "
1978 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001979 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001980
1981 elif isinstance( expectedState, types.ListType ):
1982 for intents in intentsDict:
1983 if not any( state == intents.get( 'state' ) for state in
1984 expectedState ):
1985 main.log.debug( self.name + " : Intent ID - " +
1986 intents.get( 'id' ) +
1987 " actual state = " +
1988 intents.get( 'state' ) +
1989 " does not equal expected states = "
1990 + str( expectedState ) )
1991 returnValue = main.FALSE
1992
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001993 if returnValue == main.TRUE:
1994 main.log.info( self.name + ": All " +
1995 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001996 " intents are in " + str( expectedState ) +
1997 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001998 return returnValue
1999 except TypeError:
2000 main.log.exception( self.name + ": Object not as expected" )
2001 return None
2002 except pexpect.EOF:
2003 main.log.error( self.name + ": EOF exception found" )
2004 main.log.error( self.name + ": " + self.handle.before )
2005 main.cleanup()
2006 main.exit()
2007 except Exception:
2008 main.log.exception( self.name + ": Uncaught exception!" )
2009 main.cleanup()
2010 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002011
GlennRCed771242016-01-13 17:02:47 -08002012 def checkIntentSummary( self, timeout=60 ):
2013 """
2014 Description:
2015 Check the number of installed intents.
2016 Optional:
2017 timeout - the timeout for pexcept
2018 Return:
2019 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2020 , otherwise, returns main.FALSE.
2021 """
2022
2023 try:
2024 cmd = "intents -s -j"
2025
2026 # Check response if something wrong
2027 response = self.sendline( cmd, timeout=timeout )
2028 if response == None:
2029 return main.False
2030 response = json.loads( response )
2031
2032 # get total and installed number, see if they are match
2033 allState = response.get( 'all' )
2034 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002035 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002036 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002037 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002038 return main.FALSE
2039
Jon Hallc6793552016-01-19 14:18:37 -08002040 except ( TypeError, ValueError ):
2041 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002042 return None
2043 except pexpect.EOF:
2044 main.log.error( self.name + ": EOF exception found" )
2045 main.log.error( self.name + ": " + self.handle.before )
2046 main.cleanup()
2047 main.exit()
2048 except Exception:
2049 main.log.exception( self.name + ": Uncaught exception!" )
2050 main.cleanup()
2051 main.exit()
2052
2053 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002054 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002055 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002056 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002057 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002058 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002059 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002060 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002061 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002062 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002063 cmdStr += " -j "
2064 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002065 handle = self.sendline( cmdStr, timeout=timeout )
2066 assert "Command not found:" not in handle, handle
2067 if re.search( "Error:", handle ):
2068 main.log.error( self.name + ": flows() response: " +
2069 str( handle ) )
2070 return handle
2071 except AssertionError:
2072 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002073 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002074 except TypeError:
2075 main.log.exception( self.name + ": Object not as expected" )
2076 return None
Jon Hallc6793552016-01-19 14:18:37 -08002077 except pexpect.TIMEOUT:
2078 main.log.error( self.name + ": ONOS timeout" )
2079 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002080 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002081 main.log.error( self.name + ": EOF exception found" )
2082 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002083 main.cleanup()
2084 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002085 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002086 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002087 main.cleanup()
2088 main.exit()
2089
GlennRCed771242016-01-13 17:02:47 -08002090
Jon Hallc6793552016-01-19 14:18:37 -08002091 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002092 """
2093 Description:
GlennRCed771242016-01-13 17:02:47 -08002094 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002095 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2096 if the count of those states is 0, which means all current flows
2097 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002098 Optional:
GlennRCed771242016-01-13 17:02:47 -08002099 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002100 Return:
2101 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002102 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002103 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002104 """
2105 try:
GlennRCed771242016-01-13 17:02:47 -08002106 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2107 checkedStates = []
2108 statesCount = [0, 0, 0, 0]
2109 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002110 rawFlows = self.flows( state=s, timeout = timeout )
2111 checkedStates.append( json.loads( rawFlows ) )
2112 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002113 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002114 try:
2115 statesCount[i] += int( c.get( "flowCount" ) )
2116 except TypeError:
2117 main.log.exception( "Json object not as expected" )
2118 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002119
GlennRCed771242016-01-13 17:02:47 -08002120 # We want to count PENDING_ADD if isPENDING is true
2121 if isPENDING:
2122 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2123 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002124 else:
GlennRCed771242016-01-13 17:02:47 -08002125 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2126 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002127 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002128 except ( TypeError, ValueError ):
2129 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002130 return None
2131 except pexpect.EOF:
2132 main.log.error( self.name + ": EOF exception found" )
2133 main.log.error( self.name + ": " + self.handle.before )
2134 main.cleanup()
2135 main.exit()
2136 except Exception:
2137 main.log.exception( self.name + ": Uncaught exception!" )
2138 main.cleanup()
2139 main.exit()
2140
GlennRCed771242016-01-13 17:02:47 -08002141 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2142 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002143 """
andrewonlab87852b02014-11-19 18:44:19 -05002144 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002145 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002146 a specific point-to-point intent definition
2147 Required:
GlennRCed771242016-01-13 17:02:47 -08002148 * ingress: specify source dpid
2149 * egress: specify destination dpid
2150 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002151 Optional:
GlennRCed771242016-01-13 17:02:47 -08002152 * offset: the keyOffset is where the next batch of intents
2153 will be installed
2154 Returns: If failed to push test intents, it will returen None,
2155 if successful, return true.
2156 Timeout expection will return None,
2157 TypeError will return false
2158 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002159 """
andrewonlab87852b02014-11-19 18:44:19 -05002160 try:
GlennRCed771242016-01-13 17:02:47 -08002161 if background:
2162 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002163 else:
GlennRCed771242016-01-13 17:02:47 -08002164 back = ""
2165 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002166 ingress,
2167 egress,
2168 batchSize,
2169 offset,
2170 back )
GlennRCed771242016-01-13 17:02:47 -08002171 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002172 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002173 main.log.info( response )
2174 if response == None:
2175 return None
2176
2177 # TODO: We should handle if there is failure in installation
2178 return main.TRUE
2179
Jon Hallc6793552016-01-19 14:18:37 -08002180 except AssertionError:
2181 main.log.exception( "" )
2182 return None
GlennRCed771242016-01-13 17:02:47 -08002183 except pexpect.TIMEOUT:
2184 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002185 return None
andrewonlab87852b02014-11-19 18:44:19 -05002186 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002189 main.cleanup()
2190 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002193 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002194 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002195 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002196 main.cleanup()
2197 main.exit()
2198
YPZhangf6f14a02016-01-28 15:17:31 -08002199 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002200 """
2201 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002202 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002203 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002204 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002205 """
YPZhange3109a72016-02-02 11:25:37 -08002206
YPZhangb5d3f832016-01-23 22:54:26 -08002207 try:
YPZhange3109a72016-02-02 11:25:37 -08002208 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002209 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002210 totalFlows = self.sendline( cmd, timeout=timeout )
2211
2212 if totalFlows == None:
2213 # if timeout, we will get total number of all flows, and subtract other states
2214 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2215 checkedStates = []
2216 totalFlows = 0
2217 statesCount = [0, 0, 0, 0]
2218
2219 # get total flows from summary
2220 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2221 totalFlows = int( response.get("flows") )
2222
2223 for s in states:
2224 rawFlows = self.flows( state=s, timeout = timeout )
2225 if rawFlows == None:
2226 # if timeout, return the total flows number from summary command
2227 return totalFlows
2228 checkedStates.append( json.loads( rawFlows ) )
2229
2230 # Calculate ADDED flows number, equal total subtracts others
2231 for i in range( len( states ) ):
2232 for c in checkedStates[i]:
2233 try:
2234 statesCount[i] += int( c.get( "flowCount" ) )
2235 except TypeError:
2236 main.log.exception( "Json object not as expected" )
2237 totalFlows = totalFlows - int( statesCount[i] )
2238 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2239
2240 return totalFlows
2241
2242 return totalFlows
2243
YPZhangb5d3f832016-01-23 22:54:26 -08002244 except TypeError:
2245 main.log.exception( self.name + ": Object not as expected" )
2246 return None
2247 except pexpect.EOF:
2248 main.log.error( self.name + ": EOF exception found" )
2249 main.log.error( self.name + ": " + self.handle.before )
2250 main.cleanup()
2251 main.exit()
2252 except Exception:
2253 main.log.exception( self.name + ": Uncaught exception!" )
2254 main.cleanup()
2255 main.exit()
2256
2257 def getTotalIntentsNum( self ):
2258 """
2259 Description:
2260 Get the total number of intents, include every states.
2261 Return:
2262 The number of intents
2263 """
2264 try:
2265 cmd = "summary -j"
2266 response = self.sendline( cmd )
2267 if response == None:
2268 return -1
2269 response = json.loads( response )
2270 return int( response.get("intents") )
2271 except TypeError:
2272 main.log.exception( self.name + ": Object not as expected" )
2273 return None
2274 except pexpect.EOF:
2275 main.log.error( self.name + ": EOF exception found" )
2276 main.log.error( self.name + ": " + self.handle.before )
2277 main.cleanup()
2278 main.exit()
2279 except Exception:
2280 main.log.exception( self.name + ": Uncaught exception!" )
2281 main.cleanup()
2282 main.exit()
2283
kelvin-onlabd3b64892015-01-20 13:26:24 -08002284 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002285 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002287 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002288 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002289 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002290 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002291 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002292 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002293 cmdStr += " -j"
2294 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002295 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002296 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002297 except AssertionError:
2298 main.log.exception( "" )
2299 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002300 except TypeError:
2301 main.log.exception( self.name + ": Object not as expected" )
2302 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002303 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002304 main.log.error( self.name + ": EOF exception found" )
2305 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002306 main.cleanup()
2307 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002308 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002309 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002310 main.cleanup()
2311 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002312
kelvin-onlabd3b64892015-01-20 13:26:24 -08002313 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002314 """
2315 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002316 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002317 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002318 """
andrewonlab867212a2014-10-22 20:13:38 -04002319 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002320 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002321 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002322 cmdStr += " -j"
2323 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002324 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002325 if handle:
2326 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002327 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002328 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002329 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002330 else:
2331 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002332 except AssertionError:
2333 main.log.exception( "" )
2334 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002335 except TypeError:
2336 main.log.exception( self.name + ": Object not as expected" )
2337 return None
andrewonlab867212a2014-10-22 20:13:38 -04002338 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002339 main.log.error( self.name + ": EOF exception found" )
2340 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002341 main.cleanup()
2342 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002343 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002344 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002345 main.cleanup()
2346 main.exit()
2347
kelvin8ec71442015-01-15 16:57:00 -08002348 # Wrapper functions ****************
2349 # Wrapper functions use existing driver
2350 # functions and extends their use case.
2351 # For example, we may use the output of
2352 # a normal driver function, and parse it
2353 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002354
kelvin-onlabd3b64892015-01-20 13:26:24 -08002355 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002356 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002357 Description:
2358 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002359 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002360 try:
kelvin8ec71442015-01-15 16:57:00 -08002361 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002362 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002363 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002364
kelvin8ec71442015-01-15 16:57:00 -08002365 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002366 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2367 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002368 match = re.search('id=0x([\da-f]+),', intents)
2369 if match:
2370 tmpId = match.group()[3:-1]
2371 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002372 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002373
Jon Halld4d4b372015-01-28 16:02:41 -08002374 except TypeError:
2375 main.log.exception( self.name + ": Object not as expected" )
2376 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002377 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002378 main.log.error( self.name + ": EOF exception found" )
2379 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002380 main.cleanup()
2381 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002382 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002383 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002384 main.cleanup()
2385 main.exit()
2386
Jon Hall30b82fa2015-03-04 17:15:43 -08002387 def FlowAddedCount( self, deviceId ):
2388 """
2389 Determine the number of flow rules for the given device id that are
2390 in the added state
2391 """
2392 try:
2393 cmdStr = "flows any " + str( deviceId ) + " | " +\
2394 "grep 'state=ADDED' | wc -l"
2395 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002396 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002397 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002398 except AssertionError:
2399 main.log.exception( "" )
2400 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002401 except pexpect.EOF:
2402 main.log.error( self.name + ": EOF exception found" )
2403 main.log.error( self.name + ": " + self.handle.before )
2404 main.cleanup()
2405 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002406 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002407 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002408 main.cleanup()
2409 main.exit()
2410
kelvin-onlabd3b64892015-01-20 13:26:24 -08002411 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002412 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002413 Use 'devices' function to obtain list of all devices
2414 and parse the result to obtain a list of all device
2415 id's. Returns this list. Returns empty list if no
2416 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002417 List is ordered sequentially
2418
andrewonlab3e15ead2014-10-15 14:21:34 -04002419 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002420 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002421 the ids. By obtaining the list of device ids on the fly,
2422 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002423 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002424 try:
kelvin8ec71442015-01-15 16:57:00 -08002425 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 devicesStr = self.devices( jsonFormat=False )
2427 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002428
kelvin-onlabd3b64892015-01-20 13:26:24 -08002429 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002430 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002431 return idList
kelvin8ec71442015-01-15 16:57:00 -08002432
2433 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002434 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002435 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002436 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002437 # Split list further into arguments before and after string
2438 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002439 # append to idList
2440 for arg in tempList:
2441 idList.append( arg.split( "id=" )[ 1 ] )
2442 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002443
Jon Halld4d4b372015-01-28 16:02:41 -08002444 except TypeError:
2445 main.log.exception( self.name + ": Object not as expected" )
2446 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002447 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002448 main.log.error( self.name + ": EOF exception found" )
2449 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002450 main.cleanup()
2451 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002452 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002453 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002454 main.cleanup()
2455 main.exit()
2456
kelvin-onlabd3b64892015-01-20 13:26:24 -08002457 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002458 """
andrewonlab7c211572014-10-15 16:45:20 -04002459 Uses 'nodes' function to obtain list of all nodes
2460 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002461 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002462 Returns:
2463 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002464 """
andrewonlab7c211572014-10-15 16:45:20 -04002465 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002466 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002467 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002468 # Sample nodesStr output
2469 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002470 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002471 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002472 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002473 nodesJson = json.loads( nodesStr )
2474 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002475 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002476 except ( TypeError, ValueError ):
2477 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002478 return None
andrewonlab7c211572014-10-15 16:45:20 -04002479 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002480 main.log.error( self.name + ": EOF exception found" )
2481 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002482 main.cleanup()
2483 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002484 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002485 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002486 main.cleanup()
2487 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002488
kelvin-onlabd3b64892015-01-20 13:26:24 -08002489 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002490 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002491 Return the first device from the devices api whose 'id' contains 'dpid'
2492 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002493 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002494 try:
kelvin8ec71442015-01-15 16:57:00 -08002495 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002496 return None
2497 else:
kelvin8ec71442015-01-15 16:57:00 -08002498 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002499 rawDevices = self.devices()
2500 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002501 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002502 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002503 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2504 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002505 return device
2506 return None
Jon Hallc6793552016-01-19 14:18:37 -08002507 except ( TypeError, ValueError ):
2508 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002509 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002510 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002511 main.log.error( self.name + ": EOF exception found" )
2512 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002513 main.cleanup()
2514 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002515 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002516 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002517 main.cleanup()
2518 main.exit()
2519
kelvin-onlabd3b64892015-01-20 13:26:24 -08002520 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002521 """
Jon Hallefbd9792015-03-05 16:11:36 -08002522 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002523 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002524 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002525
Jon Hall42db6dc2014-10-24 19:03:48 -04002526 Params: ip = ip used for the onos cli
2527 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002528 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002529 logLevel = level to log to. Currently accepts
2530 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002531
2532
kelvin-onlabd3b64892015-01-20 13:26:24 -08002533 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002534
Jon Hallefbd9792015-03-05 16:11:36 -08002535 Returns: main.TRUE if the number of switches and links are correct,
2536 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002537 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002538 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002539 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002540 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002541 if topology == {}:
2542 return main.ERROR
2543 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002544 # Is the number of switches is what we expected
2545 devices = topology.get( 'devices', False )
2546 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002547 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002548 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002549 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002550 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002551 linkCheck = ( int( links ) == int( numolink ) )
2552 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002553 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002554 output += "The number of links and switches match " +\
2555 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002556 result = main.TRUE
2557 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002558 output += "The number of links and switches does not match " +\
2559 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002560 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002561 output = output + "\n ONOS sees %i devices (%i expected) \
2562 and %i links (%i expected)" % (
2563 int( devices ), int( numoswitch ), int( links ),
2564 int( numolink ) )
2565 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002566 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002567 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002568 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002569 else:
Jon Hall390696c2015-05-05 17:13:41 -07002570 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002571 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002572 except TypeError:
2573 main.log.exception( self.name + ": Object not as expected" )
2574 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002575 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002576 main.log.error( self.name + ": EOF exception found" )
2577 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002578 main.cleanup()
2579 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002580 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002581 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002582 main.cleanup()
2583 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002584
kelvin-onlabd3b64892015-01-20 13:26:24 -08002585 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002586 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002587 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002588 deviceId must be the id of a device as seen in the onos devices command
2589 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002590 role must be either master, standby, or none
2591
Jon Halle3f39ff2015-01-13 11:50:53 -08002592 Returns:
2593 main.TRUE or main.FALSE based on argument verification and
2594 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002595 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002596 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002597 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002598 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002599 cmdStr = "device-role " +\
2600 str( deviceId ) + " " +\
2601 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002602 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002604 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002605 if re.search( "Error", handle ):
2606 # end color output to escape any colours
2607 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002608 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002609 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002610 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002611 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002612 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002613 main.log.error( "Invalid 'role' given to device_role(). " +
2614 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002615 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002616 except AssertionError:
2617 main.log.exception( "" )
2618 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002619 except TypeError:
2620 main.log.exception( self.name + ": Object not as expected" )
2621 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002622 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002623 main.log.error( self.name + ": EOF exception found" )
2624 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002625 main.cleanup()
2626 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002627 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002628 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002629 main.cleanup()
2630 main.exit()
2631
kelvin-onlabd3b64892015-01-20 13:26:24 -08002632 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002633 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002634 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002635 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002636 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002637 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002638 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002639 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002641 cmdStr += " -j"
2642 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002643 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002644 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002645 except AssertionError:
2646 main.log.exception( "" )
2647 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002648 except TypeError:
2649 main.log.exception( self.name + ": Object not as expected" )
2650 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002651 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002652 main.log.error( self.name + ": EOF exception found" )
2653 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002654 main.cleanup()
2655 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002656 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002657 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002658 main.cleanup()
2659 main.exit()
2660
kelvin-onlabd3b64892015-01-20 13:26:24 -08002661 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002662 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002663 CLI command to get the current leader for the Election test application
2664 NOTE: Requires installation of the onos-app-election feature
2665 Returns: Node IP of the leader if one exists
2666 None if none exists
2667 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002668 """
Jon Hall94fd0472014-12-08 11:52:42 -08002669 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002670 cmdStr = "election-test-leader"
2671 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002672 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002673 # Leader
2674 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002675 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002676 nodeSearch = re.search( leaderPattern, response )
2677 if nodeSearch:
2678 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002679 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002680 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002681 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002682 # no leader
2683 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002684 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002685 nullSearch = re.search( nullPattern, response )
2686 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002687 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002688 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002689 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002690 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002691 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002692 if re.search( errorPattern, response ):
2693 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002694 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002695 return main.FALSE
2696 else:
Jon Hall390696c2015-05-05 17:13:41 -07002697 main.log.error( "Error in electionTestLeader on " + self.name +
2698 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002699 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002700 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002701 except AssertionError:
2702 main.log.exception( "" )
2703 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002704 except TypeError:
2705 main.log.exception( self.name + ": Object not as expected" )
2706 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002707 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002708 main.log.error( self.name + ": EOF exception found" )
2709 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002710 main.cleanup()
2711 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002712 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002713 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002714 main.cleanup()
2715 main.exit()
2716
kelvin-onlabd3b64892015-01-20 13:26:24 -08002717 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002718 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002719 CLI command to run for leadership of the Election test application.
2720 NOTE: Requires installation of the onos-app-election feature
2721 Returns: Main.TRUE on success
2722 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002723 """
Jon Hall94fd0472014-12-08 11:52:42 -08002724 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 cmdStr = "election-test-run"
2726 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002727 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002728 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002729 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002730 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002731 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002732 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002733 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002734 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002735 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002736 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002737 errorPattern = "Command\snot\sfound"
2738 if re.search( errorPattern, response ):
2739 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002740 return main.FALSE
2741 else:
Jon Hall390696c2015-05-05 17:13:41 -07002742 main.log.error( "Error in electionTestRun on " + self.name +
2743 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002744 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002745 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002746 except AssertionError:
2747 main.log.exception( "" )
2748 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002749 except TypeError:
2750 main.log.exception( self.name + ": Object not as expected" )
2751 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002753 main.log.error( self.name + ": EOF exception found" )
2754 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002755 main.cleanup()
2756 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002757 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002758 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002759 main.cleanup()
2760 main.exit()
2761
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002763 """
Jon Hall94fd0472014-12-08 11:52:42 -08002764 * CLI command to withdraw the local node from leadership election for
2765 * the Election test application.
2766 #NOTE: Requires installation of the onos-app-election feature
2767 Returns: Main.TRUE on success
2768 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002769 """
Jon Hall94fd0472014-12-08 11:52:42 -08002770 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002771 cmdStr = "election-test-withdraw"
2772 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002773 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002774 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002775 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002776 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002777 if re.search( successPattern, response ):
2778 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002779 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002780 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002781 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002782 errorPattern = "Command\snot\sfound"
2783 if re.search( errorPattern, response ):
2784 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002785 return main.FALSE
2786 else:
Jon Hall390696c2015-05-05 17:13:41 -07002787 main.log.error( "Error in electionTestWithdraw on " +
2788 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002789 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002790 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002791 except AssertionError:
2792 main.log.exception( "" )
2793 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002794 except TypeError:
2795 main.log.exception( self.name + ": Object not as expected" )
2796 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002797 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002798 main.log.error( self.name + ": EOF exception found" )
2799 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002800 main.cleanup()
2801 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002802 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002803 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002804 main.cleanup()
2805 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002806
kelvin8ec71442015-01-15 16:57:00 -08002807 def getDevicePortsEnabledCount( self, dpid ):
2808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002809 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002810 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002811 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002812 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2814 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002815 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002816 if re.search( "No such device", output ):
2817 main.log.error( "Error in getting ports" )
2818 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002819 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002820 return output
Jon Hallc6793552016-01-19 14:18:37 -08002821 except AssertionError:
2822 main.log.exception( "" )
2823 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002824 except TypeError:
2825 main.log.exception( self.name + ": Object not as expected" )
2826 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002827 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002828 main.log.error( self.name + ": EOF exception found" )
2829 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002830 main.cleanup()
2831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002832 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002833 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002834 main.cleanup()
2835 main.exit()
2836
kelvin8ec71442015-01-15 16:57:00 -08002837 def getDeviceLinksActiveCount( self, dpid ):
2838 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002839 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002840 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002841 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002842 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002843 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2844 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002845 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002846 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002847 main.log.error( "Error in getting ports " )
2848 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002849 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002850 return output
Jon Hallc6793552016-01-19 14:18:37 -08002851 except AssertionError:
2852 main.log.exception( "" )
2853 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002854 except TypeError:
2855 main.log.exception( self.name + ": Object not as expected" )
2856 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002857 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002858 main.log.error( self.name + ": EOF exception found" )
2859 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002860 main.cleanup()
2861 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002862 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002863 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002864 main.cleanup()
2865 main.exit()
2866
kelvin8ec71442015-01-15 16:57:00 -08002867 def getAllIntentIds( self ):
2868 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002869 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002870 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002871 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 cmdStr = "onos:intents | grep id="
2873 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002874 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002875 if re.search( "Error", output ):
2876 main.log.error( "Error in getting ports" )
2877 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002878 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002879 return output
Jon Hallc6793552016-01-19 14:18:37 -08002880 except AssertionError:
2881 main.log.exception( "" )
2882 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002883 except TypeError:
2884 main.log.exception( self.name + ": Object not as expected" )
2885 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002886 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002887 main.log.error( self.name + ": EOF exception found" )
2888 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002889 main.cleanup()
2890 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002891 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002892 main.log.exception( self.name + ": Uncaught exception!" )
2893 main.cleanup()
2894 main.exit()
2895
Jon Hall73509952015-02-24 16:42:56 -08002896 def intentSummary( self ):
2897 """
Jon Hallefbd9792015-03-05 16:11:36 -08002898 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002899 """
2900 try:
2901 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002902 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002903 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002904 states.append( intent.get( 'state', None ) )
2905 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002906 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002907 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002908 except ( TypeError, ValueError ):
2909 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002910 return None
2911 except pexpect.EOF:
2912 main.log.error( self.name + ": EOF exception found" )
2913 main.log.error( self.name + ": " + self.handle.before )
2914 main.cleanup()
2915 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002916 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002917 main.log.exception( self.name + ": Uncaught exception!" )
2918 main.cleanup()
2919 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002920
Jon Hall61282e32015-03-19 11:34:11 -07002921 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002922 """
2923 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002924 Optional argument:
2925 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002926 """
Jon Hall63604932015-02-26 17:09:50 -08002927 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002928 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002929 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002930 cmdStr += " -j"
2931 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002932 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002933 return output
Jon Hallc6793552016-01-19 14:18:37 -08002934 except AssertionError:
2935 main.log.exception( "" )
2936 return None
Jon Hall63604932015-02-26 17:09:50 -08002937 except TypeError:
2938 main.log.exception( self.name + ": Object not as expected" )
2939 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002940 except pexpect.EOF:
2941 main.log.error( self.name + ": EOF exception found" )
2942 main.log.error( self.name + ": " + self.handle.before )
2943 main.cleanup()
2944 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002945 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002946 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002947 main.cleanup()
2948 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002949
acsmarsa4a4d1e2015-07-10 16:01:24 -07002950 def leaderCandidates( self, jsonFormat=True ):
2951 """
2952 Returns the output of the leaders -c command.
2953 Optional argument:
2954 * jsonFormat - boolean indicating if you want output in json
2955 """
2956 try:
2957 cmdStr = "onos:leaders -c"
2958 if jsonFormat:
2959 cmdStr += " -j"
2960 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002961 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002962 return output
Jon Hallc6793552016-01-19 14:18:37 -08002963 except AssertionError:
2964 main.log.exception( "" )
2965 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002966 except TypeError:
2967 main.log.exception( self.name + ": Object not as expected" )
2968 return None
2969 except pexpect.EOF:
2970 main.log.error( self.name + ": EOF exception found" )
2971 main.log.error( self.name + ": " + self.handle.before )
2972 main.cleanup()
2973 main.exit()
2974 except Exception:
2975 main.log.exception( self.name + ": Uncaught exception!" )
2976 main.cleanup()
2977 main.exit()
2978
Jon Hallc6793552016-01-19 14:18:37 -08002979 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002980 """
2981 Returns a list in format [leader,candidate1,candidate2,...] for a given
2982 topic parameter and an empty list if the topic doesn't exist
2983 If no leader is elected leader in the returned list will be "none"
2984 Returns None if there is a type error processing the json object
2985 """
2986 try:
Jon Hall6e709752016-02-01 13:38:46 -08002987 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08002988 rawOutput = self.sendline( cmdStr )
2989 assert "Command not found:" not in rawOutput, rawOutput
2990 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002991 results = []
2992 for dict in output:
2993 if dict["topic"] == topic:
2994 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002995 candidates = re.split( ", ", dict["candidates"][1:-1] )
2996 results.append( leader )
2997 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002998 return results
Jon Hallc6793552016-01-19 14:18:37 -08002999 except AssertionError:
3000 main.log.exception( "" )
3001 return None
3002 except ( TypeError, ValueError ):
3003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003004 return None
3005 except pexpect.EOF:
3006 main.log.error( self.name + ": EOF exception found" )
3007 main.log.error( self.name + ": " + self.handle.before )
3008 main.cleanup()
3009 main.exit()
3010 except Exception:
3011 main.log.exception( self.name + ": Uncaught exception!" )
3012 main.cleanup()
3013 main.exit()
3014
Jon Hall61282e32015-03-19 11:34:11 -07003015 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003016 """
3017 Returns the output of the intent Pending map.
3018 """
Jon Hall63604932015-02-26 17:09:50 -08003019 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003020 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003021 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003022 cmdStr += " -j"
3023 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003024 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003025 return output
Jon Hallc6793552016-01-19 14:18:37 -08003026 except AssertionError:
3027 main.log.exception( "" )
3028 return None
Jon Hall63604932015-02-26 17:09:50 -08003029 except TypeError:
3030 main.log.exception( self.name + ": Object not as expected" )
3031 return None
3032 except pexpect.EOF:
3033 main.log.error( self.name + ": EOF exception found" )
3034 main.log.error( self.name + ": " + self.handle.before )
3035 main.cleanup()
3036 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003037 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003038 main.log.exception( self.name + ": Uncaught exception!" )
3039 main.cleanup()
3040 main.exit()
3041
Jon Hall61282e32015-03-19 11:34:11 -07003042 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003043 """
3044 Returns the output of the raft partitions command for ONOS.
3045 """
Jon Hall61282e32015-03-19 11:34:11 -07003046 # Sample JSON
3047 # {
3048 # "leader": "tcp://10.128.30.11:7238",
3049 # "members": [
3050 # "tcp://10.128.30.11:7238",
3051 # "tcp://10.128.30.17:7238",
3052 # "tcp://10.128.30.13:7238",
3053 # ],
3054 # "name": "p1",
3055 # "term": 3
3056 # },
Jon Hall63604932015-02-26 17:09:50 -08003057 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003058 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003059 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003060 cmdStr += " -j"
3061 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003062 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003063 return output
Jon Hallc6793552016-01-19 14:18:37 -08003064 except AssertionError:
3065 main.log.exception( "" )
3066 return None
Jon Hall63604932015-02-26 17:09:50 -08003067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return None
3070 except pexpect.EOF:
3071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
3073 main.cleanup()
3074 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003075 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003076 main.log.exception( self.name + ": Uncaught exception!" )
3077 main.cleanup()
3078 main.exit()
3079
Jon Hallbe379602015-03-24 13:39:32 -07003080 def apps( self, jsonFormat=True ):
3081 """
3082 Returns the output of the apps command for ONOS. This command lists
3083 information about installed ONOS applications
3084 """
3085 # Sample JSON object
3086 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3087 # "description":"ONOS OpenFlow protocol southbound providers",
3088 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3089 # "features":"[onos-openflow]","state":"ACTIVE"}]
3090 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003091 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003092 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003093 cmdStr += " -j"
3094 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003095 assert "Command not found:" not in output, output
3096 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003097 return output
Jon Hallbe379602015-03-24 13:39:32 -07003098 # FIXME: look at specific exceptions/Errors
3099 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003100 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003101 return None
3102 except TypeError:
3103 main.log.exception( self.name + ": Object not as expected" )
3104 return None
3105 except pexpect.EOF:
3106 main.log.error( self.name + ": EOF exception found" )
3107 main.log.error( self.name + ": " + self.handle.before )
3108 main.cleanup()
3109 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003110 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003111 main.log.exception( self.name + ": Uncaught exception!" )
3112 main.cleanup()
3113 main.exit()
3114
Jon Hall146f1522015-03-24 15:33:24 -07003115 def appStatus( self, appName ):
3116 """
3117 Uses the onos:apps cli command to return the status of an application.
3118 Returns:
3119 "ACTIVE" - If app is installed and activated
3120 "INSTALLED" - If app is installed and deactivated
3121 "UNINSTALLED" - If app is not installed
3122 None - on error
3123 """
Jon Hall146f1522015-03-24 15:33:24 -07003124 try:
3125 if not isinstance( appName, types.StringType ):
3126 main.log.error( self.name + ".appStatus(): appName must be" +
3127 " a string" )
3128 return None
3129 output = self.apps( jsonFormat=True )
3130 appsJson = json.loads( output )
3131 state = None
3132 for app in appsJson:
3133 if appName == app.get('name'):
3134 state = app.get('state')
3135 break
3136 if state == "ACTIVE" or state == "INSTALLED":
3137 return state
3138 elif state is None:
3139 return "UNINSTALLED"
3140 elif state:
3141 main.log.error( "Unexpected state from 'onos:apps': " +
3142 str( state ) )
3143 return state
Jon Hallc6793552016-01-19 14:18:37 -08003144 except ( TypeError, ValueError ):
3145 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3146 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003147 return None
3148 except pexpect.EOF:
3149 main.log.error( self.name + ": EOF exception found" )
3150 main.log.error( self.name + ": " + self.handle.before )
3151 main.cleanup()
3152 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003153 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003154 main.log.exception( self.name + ": Uncaught exception!" )
3155 main.cleanup()
3156 main.exit()
3157
Jon Hallbe379602015-03-24 13:39:32 -07003158 def app( self, appName, option ):
3159 """
3160 Interacts with the app command for ONOS. This command manages
3161 application inventory.
3162 """
Jon Hallbe379602015-03-24 13:39:32 -07003163 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003164 # Validate argument types
3165 valid = True
3166 if not isinstance( appName, types.StringType ):
3167 main.log.error( self.name + ".app(): appName must be a " +
3168 "string" )
3169 valid = False
3170 if not isinstance( option, types.StringType ):
3171 main.log.error( self.name + ".app(): option must be a string" )
3172 valid = False
3173 if not valid:
3174 return main.FALSE
3175 # Validate Option
3176 option = option.lower()
3177 # NOTE: Install may become a valid option
3178 if option == "activate":
3179 pass
3180 elif option == "deactivate":
3181 pass
3182 elif option == "uninstall":
3183 pass
3184 else:
3185 # Invalid option
3186 main.log.error( "The ONOS app command argument only takes " +
3187 "the values: (activate|deactivate|uninstall)" +
3188 "; was given '" + option + "'")
3189 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003190 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003191 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003192 if "Error executing command" in output:
3193 main.log.error( "Error in processing onos:app command: " +
3194 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003195 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003196 elif "No such application" in output:
3197 main.log.error( "The application '" + appName +
3198 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003199 return main.FALSE
3200 elif "Command not found:" in output:
3201 main.log.error( "Error in processing onos:app command: " +
3202 str( output ) )
3203 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003204 elif "Unsupported command:" in output:
3205 main.log.error( "Incorrect command given to 'app': " +
3206 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003207 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003208 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003209 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003210 return main.TRUE
3211 except TypeError:
3212 main.log.exception( self.name + ": Object not as expected" )
3213 return main.ERROR
3214 except pexpect.EOF:
3215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
3217 main.cleanup()
3218 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003219 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003220 main.log.exception( self.name + ": Uncaught exception!" )
3221 main.cleanup()
3222 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003223
Jon Hallbd16b922015-03-26 17:53:15 -07003224 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003225 """
3226 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003227 appName is the hierarchical app name, not the feature name
3228 If check is True, method will check the status of the app after the
3229 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003230 Returns main.TRUE if the command was successfully sent
3231 main.FALSE if the cli responded with an error or given
3232 incorrect input
3233 """
3234 try:
3235 if not isinstance( appName, types.StringType ):
3236 main.log.error( self.name + ".activateApp(): appName must be" +
3237 " a string" )
3238 return main.FALSE
3239 status = self.appStatus( appName )
3240 if status == "INSTALLED":
3241 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003242 if check and response == main.TRUE:
3243 for i in range(10): # try 10 times then give up
3244 # TODO: Check with Thomas about this delay
3245 status = self.appStatus( appName )
3246 if status == "ACTIVE":
3247 return main.TRUE
3248 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003249 main.log.debug( "The state of application " +
3250 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003251 time.sleep( 1 )
3252 return main.FALSE
3253 else: # not 'check' or command didn't succeed
3254 return response
Jon Hall146f1522015-03-24 15:33:24 -07003255 elif status == "ACTIVE":
3256 return main.TRUE
3257 elif status == "UNINSTALLED":
3258 main.log.error( self.name + ": Tried to activate the " +
3259 "application '" + appName + "' which is not " +
3260 "installed." )
3261 else:
3262 main.log.error( "Unexpected return value from appStatus: " +
3263 str( status ) )
3264 return main.ERROR
3265 except TypeError:
3266 main.log.exception( self.name + ": Object not as expected" )
3267 return main.ERROR
3268 except pexpect.EOF:
3269 main.log.error( self.name + ": EOF exception found" )
3270 main.log.error( self.name + ": " + self.handle.before )
3271 main.cleanup()
3272 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003273 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003274 main.log.exception( self.name + ": Uncaught exception!" )
3275 main.cleanup()
3276 main.exit()
3277
Jon Hallbd16b922015-03-26 17:53:15 -07003278 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003279 """
3280 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003281 appName is the hierarchical app name, not the feature name
3282 If check is True, method will check the status of the app after the
3283 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003284 Returns main.TRUE if the command was successfully sent
3285 main.FALSE if the cli responded with an error or given
3286 incorrect input
3287 """
3288 try:
3289 if not isinstance( appName, types.StringType ):
3290 main.log.error( self.name + ".deactivateApp(): appName must " +
3291 "be a string" )
3292 return main.FALSE
3293 status = self.appStatus( appName )
3294 if status == "INSTALLED":
3295 return main.TRUE
3296 elif status == "ACTIVE":
3297 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003298 if check and response == main.TRUE:
3299 for i in range(10): # try 10 times then give up
3300 status = self.appStatus( appName )
3301 if status == "INSTALLED":
3302 return main.TRUE
3303 else:
3304 time.sleep( 1 )
3305 return main.FALSE
3306 else: # not check or command didn't succeed
3307 return response
Jon Hall146f1522015-03-24 15:33:24 -07003308 elif status == "UNINSTALLED":
3309 main.log.warn( self.name + ": Tried to deactivate the " +
3310 "application '" + appName + "' which is not " +
3311 "installed." )
3312 return main.TRUE
3313 else:
3314 main.log.error( "Unexpected return value from appStatus: " +
3315 str( status ) )
3316 return main.ERROR
3317 except TypeError:
3318 main.log.exception( self.name + ": Object not as expected" )
3319 return main.ERROR
3320 except pexpect.EOF:
3321 main.log.error( self.name + ": EOF exception found" )
3322 main.log.error( self.name + ": " + self.handle.before )
3323 main.cleanup()
3324 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003325 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003326 main.log.exception( self.name + ": Uncaught exception!" )
3327 main.cleanup()
3328 main.exit()
3329
Jon Hallbd16b922015-03-26 17:53:15 -07003330 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003331 """
3332 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003333 appName is the hierarchical app name, not the feature name
3334 If check is True, method will check the status of the app after the
3335 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003336 Returns main.TRUE if the command was successfully sent
3337 main.FALSE if the cli responded with an error or given
3338 incorrect input
3339 """
3340 # TODO: check with Thomas about the state machine for apps
3341 try:
3342 if not isinstance( appName, types.StringType ):
3343 main.log.error( self.name + ".uninstallApp(): appName must " +
3344 "be a string" )
3345 return main.FALSE
3346 status = self.appStatus( appName )
3347 if status == "INSTALLED":
3348 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003349 if check and response == main.TRUE:
3350 for i in range(10): # try 10 times then give up
3351 status = self.appStatus( appName )
3352 if status == "UNINSTALLED":
3353 return main.TRUE
3354 else:
3355 time.sleep( 1 )
3356 return main.FALSE
3357 else: # not check or command didn't succeed
3358 return response
Jon Hall146f1522015-03-24 15:33:24 -07003359 elif status == "ACTIVE":
3360 main.log.warn( self.name + ": Tried to uninstall the " +
3361 "application '" + appName + "' which is " +
3362 "currently active." )
3363 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003364 if check and response == main.TRUE:
3365 for i in range(10): # try 10 times then give up
3366 status = self.appStatus( appName )
3367 if status == "UNINSTALLED":
3368 return main.TRUE
3369 else:
3370 time.sleep( 1 )
3371 return main.FALSE
3372 else: # not check or command didn't succeed
3373 return response
Jon Hall146f1522015-03-24 15:33:24 -07003374 elif status == "UNINSTALLED":
3375 return main.TRUE
3376 else:
3377 main.log.error( "Unexpected return value from appStatus: " +
3378 str( status ) )
3379 return main.ERROR
3380 except TypeError:
3381 main.log.exception( self.name + ": Object not as expected" )
3382 return main.ERROR
3383 except pexpect.EOF:
3384 main.log.error( self.name + ": EOF exception found" )
3385 main.log.error( self.name + ": " + self.handle.before )
3386 main.cleanup()
3387 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003388 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003389 main.log.exception( self.name + ": Uncaught exception!" )
3390 main.cleanup()
3391 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003392
3393 def appIDs( self, jsonFormat=True ):
3394 """
3395 Show the mappings between app id and app names given by the 'app-ids'
3396 cli command
3397 """
3398 try:
3399 cmdStr = "app-ids"
3400 if jsonFormat:
3401 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003402 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003403 assert "Command not found:" not in output, output
3404 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003405 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003406 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003407 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003408 return None
3409 except TypeError:
3410 main.log.exception( self.name + ": Object not as expected" )
3411 return None
3412 except pexpect.EOF:
3413 main.log.error( self.name + ": EOF exception found" )
3414 main.log.error( self.name + ": " + self.handle.before )
3415 main.cleanup()
3416 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003417 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003418 main.log.exception( self.name + ": Uncaught exception!" )
3419 main.cleanup()
3420 main.exit()
3421
3422 def appToIDCheck( self ):
3423 """
3424 This method will check that each application's ID listed in 'apps' is
3425 the same as the ID listed in 'app-ids'. The check will also check that
3426 there are no duplicate IDs issued. Note that an app ID should be
3427 a globaly unique numerical identifier for app/app-like features. Once
3428 an ID is registered, the ID is never freed up so that if an app is
3429 reinstalled it will have the same ID.
3430
3431 Returns: main.TRUE if the check passes and
3432 main.FALSE if the check fails or
3433 main.ERROR if there is some error in processing the test
3434 """
3435 try:
Jon Hall390696c2015-05-05 17:13:41 -07003436 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003437 rawJson = self.appIDs( jsonFormat=True )
3438 if rawJson:
3439 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003440 else:
Jon Hallc6793552016-01-19 14:18:37 -08003441 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003442 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003443 rawJson = self.apps( jsonFormat=True )
3444 if rawJson:
3445 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003446 else:
Jon Hallc6793552016-01-19 14:18:37 -08003447 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003448 bail = True
3449 if bail:
3450 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003451 result = main.TRUE
3452 for app in apps:
3453 appID = app.get( 'id' )
3454 if appID is None:
3455 main.log.error( "Error parsing app: " + str( app ) )
3456 result = main.FALSE
3457 appName = app.get( 'name' )
3458 if appName is None:
3459 main.log.error( "Error parsing app: " + str( app ) )
3460 result = main.FALSE
3461 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003462 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003463 # main.log.debug( "Comparing " + str( app ) + " to " +
3464 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003465 if not current: # if ids doesn't have this id
3466 result = main.FALSE
3467 main.log.error( "'app-ids' does not have the ID for " +
3468 str( appName ) + " that apps does." )
3469 elif len( current ) > 1:
3470 # there is more than one app with this ID
3471 result = main.FALSE
3472 # We will log this later in the method
3473 elif not current[0][ 'name' ] == appName:
3474 currentName = current[0][ 'name' ]
3475 result = main.FALSE
3476 main.log.error( "'app-ids' has " + str( currentName ) +
3477 " registered under id:" + str( appID ) +
3478 " but 'apps' has " + str( appName ) )
3479 else:
3480 pass # id and name match!
3481 # now make sure that app-ids has no duplicates
3482 idsList = []
3483 namesList = []
3484 for item in ids:
3485 idsList.append( item[ 'id' ] )
3486 namesList.append( item[ 'name' ] )
3487 if len( idsList ) != len( set( idsList ) ) or\
3488 len( namesList ) != len( set( namesList ) ):
3489 main.log.error( "'app-ids' has some duplicate entries: \n"
3490 + json.dumps( ids,
3491 sort_keys=True,
3492 indent=4,
3493 separators=( ',', ': ' ) ) )
3494 result = main.FALSE
3495 return result
Jon Hallc6793552016-01-19 14:18:37 -08003496 except ( TypeError, ValueError ):
3497 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003498 return main.ERROR
3499 except pexpect.EOF:
3500 main.log.error( self.name + ": EOF exception found" )
3501 main.log.error( self.name + ": " + self.handle.before )
3502 main.cleanup()
3503 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003504 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003505 main.log.exception( self.name + ": Uncaught exception!" )
3506 main.cleanup()
3507 main.exit()
3508
Jon Hallfb760a02015-04-13 15:35:03 -07003509 def getCfg( self, component=None, propName=None, short=False,
3510 jsonFormat=True ):
3511 """
3512 Get configuration settings from onos cli
3513 Optional arguments:
3514 component - Optionally only list configurations for a specific
3515 component. If None, all components with configurations
3516 are displayed. Case Sensitive string.
3517 propName - If component is specified, propName option will show
3518 only this specific configuration from that component.
3519 Case Sensitive string.
3520 jsonFormat - Returns output as json. Note that this will override
3521 the short option
3522 short - Short, less verbose, version of configurations.
3523 This is overridden by the json option
3524 returns:
3525 Output from cli as a string or None on error
3526 """
3527 try:
3528 baseStr = "cfg"
3529 cmdStr = " get"
3530 componentStr = ""
3531 if component:
3532 componentStr += " " + component
3533 if propName:
3534 componentStr += " " + propName
3535 if jsonFormat:
3536 baseStr += " -j"
3537 elif short:
3538 baseStr += " -s"
3539 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003540 assert "Command not found:" not in output, output
3541 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003542 return output
3543 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003544 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003545 return None
3546 except TypeError:
3547 main.log.exception( self.name + ": Object not as expected" )
3548 return None
3549 except pexpect.EOF:
3550 main.log.error( self.name + ": EOF exception found" )
3551 main.log.error( self.name + ": " + self.handle.before )
3552 main.cleanup()
3553 main.exit()
3554 except Exception:
3555 main.log.exception( self.name + ": Uncaught exception!" )
3556 main.cleanup()
3557 main.exit()
3558
3559 def setCfg( self, component, propName, value=None, check=True ):
3560 """
3561 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003562 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003563 component - The case sensitive name of the component whose
3564 property is to be set
3565 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003566 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003567 value - The value to set the property to. If None, will unset the
3568 property and revert it to it's default value(if applicable)
3569 check - Boolean, Check whether the option was successfully set this
3570 only applies when a value is given.
3571 returns:
3572 main.TRUE on success or main.FALSE on failure. If check is False,
3573 will return main.TRUE unless there is an error
3574 """
3575 try:
3576 baseStr = "cfg"
3577 cmdStr = " set " + str( component ) + " " + str( propName )
3578 if value is not None:
3579 cmdStr += " " + str( value )
3580 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003581 assert "Command not found:" not in output, output
3582 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003583 if value and check:
3584 results = self.getCfg( component=str( component ),
3585 propName=str( propName ),
3586 jsonFormat=True )
3587 # Check if current value is what we just set
3588 try:
3589 jsonOutput = json.loads( results )
3590 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003591 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003592 main.log.exception( "Error parsing cfg output" )
3593 main.log.error( "output:" + repr( results ) )
3594 return main.FALSE
3595 if current == str( value ):
3596 return main.TRUE
3597 return main.FALSE
3598 return main.TRUE
3599 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003600 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003601 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003602 except ( TypeError, ValueError ):
3603 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003604 return main.FALSE
3605 except pexpect.EOF:
3606 main.log.error( self.name + ": EOF exception found" )
3607 main.log.error( self.name + ": " + self.handle.before )
3608 main.cleanup()
3609 main.exit()
3610 except Exception:
3611 main.log.exception( self.name + ": Uncaught exception!" )
3612 main.cleanup()
3613 main.exit()
3614
Jon Hall390696c2015-05-05 17:13:41 -07003615 def setTestAdd( self, setName, values ):
3616 """
3617 CLI command to add elements to a distributed set.
3618 Arguments:
3619 setName - The name of the set to add to.
3620 values - The value(s) to add to the set, space seperated.
3621 Example usages:
3622 setTestAdd( "set1", "a b c" )
3623 setTestAdd( "set2", "1" )
3624 returns:
3625 main.TRUE on success OR
3626 main.FALSE if elements were already in the set OR
3627 main.ERROR on error
3628 """
3629 try:
3630 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3631 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003632 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003633 try:
3634 # TODO: Maybe make this less hardcoded
3635 # ConsistentMap Exceptions
3636 assert "org.onosproject.store.service" not in output
3637 # Node not leader
3638 assert "java.lang.IllegalStateException" not in output
3639 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003640 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003641 "command: " + str( output ) )
3642 retryTime = 30 # Conservative time, given by Madan
3643 main.log.info( "Waiting " + str( retryTime ) +
3644 "seconds before retrying." )
3645 time.sleep( retryTime ) # Due to change in mastership
3646 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003647 assert "Error executing command" not in output
3648 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3649 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3650 main.log.info( self.name + ": " + output )
3651 if re.search( positiveMatch, output):
3652 return main.TRUE
3653 elif re.search( negativeMatch, output):
3654 return main.FALSE
3655 else:
3656 main.log.error( self.name + ": setTestAdd did not" +
3657 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003658 main.log.debug( self.name + " actual: " + repr( output ) )
3659 return main.ERROR
3660 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003661 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003662 return main.ERROR
3663 except TypeError:
3664 main.log.exception( self.name + ": Object not as expected" )
3665 return main.ERROR
3666 except pexpect.EOF:
3667 main.log.error( self.name + ": EOF exception found" )
3668 main.log.error( self.name + ": " + self.handle.before )
3669 main.cleanup()
3670 main.exit()
3671 except Exception:
3672 main.log.exception( self.name + ": Uncaught exception!" )
3673 main.cleanup()
3674 main.exit()
3675
3676 def setTestRemove( self, setName, values, clear=False, retain=False ):
3677 """
3678 CLI command to remove elements from a distributed set.
3679 Required arguments:
3680 setName - The name of the set to remove from.
3681 values - The value(s) to remove from the set, space seperated.
3682 Optional arguments:
3683 clear - Clear all elements from the set
3684 retain - Retain only the given values. (intersection of the
3685 original set and the given set)
3686 returns:
3687 main.TRUE on success OR
3688 main.FALSE if the set was not changed OR
3689 main.ERROR on error
3690 """
3691 try:
3692 cmdStr = "set-test-remove "
3693 if clear:
3694 cmdStr += "-c " + str( setName )
3695 elif retain:
3696 cmdStr += "-r " + str( setName ) + " " + str( values )
3697 else:
3698 cmdStr += str( setName ) + " " + str( values )
3699 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003700 try:
3701 # TODO: Maybe make this less hardcoded
3702 # ConsistentMap Exceptions
3703 assert "org.onosproject.store.service" not in output
3704 # Node not leader
3705 assert "java.lang.IllegalStateException" not in output
3706 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003707 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003708 "command: " + str( output ) )
3709 retryTime = 30 # Conservative time, given by Madan
3710 main.log.info( "Waiting " + str( retryTime ) +
3711 "seconds before retrying." )
3712 time.sleep( retryTime ) # Due to change in mastership
3713 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003714 assert "Command not found:" not in output, output
3715 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003716 main.log.info( self.name + ": " + output )
3717 if clear:
3718 pattern = "Set " + str( setName ) + " cleared"
3719 if re.search( pattern, output ):
3720 return main.TRUE
3721 elif retain:
3722 positivePattern = str( setName ) + " was pruned to contain " +\
3723 "only elements of set \[(.*)\]"
3724 negativePattern = str( setName ) + " was not changed by " +\
3725 "retaining only elements of the set " +\
3726 "\[(.*)\]"
3727 if re.search( positivePattern, output ):
3728 return main.TRUE
3729 elif re.search( negativePattern, output ):
3730 return main.FALSE
3731 else:
3732 positivePattern = "\[(.*)\] was removed from the set " +\
3733 str( setName )
3734 if ( len( values.split() ) == 1 ):
3735 negativePattern = "\[(.*)\] was not in set " +\
3736 str( setName )
3737 else:
3738 negativePattern = "No element of \[(.*)\] was in set " +\
3739 str( setName )
3740 if re.search( positivePattern, output ):
3741 return main.TRUE
3742 elif re.search( negativePattern, output ):
3743 return main.FALSE
3744 main.log.error( self.name + ": setTestRemove did not" +
3745 " match expected output" )
3746 main.log.debug( self.name + " expected: " + pattern )
3747 main.log.debug( self.name + " actual: " + repr( output ) )
3748 return main.ERROR
3749 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003750 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003751 return main.ERROR
3752 except TypeError:
3753 main.log.exception( self.name + ": Object not as expected" )
3754 return main.ERROR
3755 except pexpect.EOF:
3756 main.log.error( self.name + ": EOF exception found" )
3757 main.log.error( self.name + ": " + self.handle.before )
3758 main.cleanup()
3759 main.exit()
3760 except Exception:
3761 main.log.exception( self.name + ": Uncaught exception!" )
3762 main.cleanup()
3763 main.exit()
3764
3765 def setTestGet( self, setName, values="" ):
3766 """
3767 CLI command to get the elements in a distributed set.
3768 Required arguments:
3769 setName - The name of the set to remove from.
3770 Optional arguments:
3771 values - The value(s) to check if in the set, space seperated.
3772 returns:
3773 main.ERROR on error OR
3774 A list of elements in the set if no optional arguments are
3775 supplied OR
3776 A tuple containing the list then:
3777 main.FALSE if the given values are not in the set OR
3778 main.TRUE if the given values are in the set OR
3779 """
3780 try:
3781 values = str( values ).strip()
3782 setName = str( setName ).strip()
3783 length = len( values.split() )
3784 containsCheck = None
3785 # Patterns to match
3786 setPattern = "\[(.*)\]"
3787 pattern = "Items in set " + setName + ":\n" + setPattern
3788 containsTrue = "Set " + setName + " contains the value " + values
3789 containsFalse = "Set " + setName + " did not contain the value " +\
3790 values
3791 containsAllTrue = "Set " + setName + " contains the the subset " +\
3792 setPattern
3793 containsAllFalse = "Set " + setName + " did not contain the the" +\
3794 " subset " + setPattern
3795
3796 cmdStr = "set-test-get "
3797 cmdStr += setName + " " + values
3798 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003799 try:
3800 # TODO: Maybe make this less hardcoded
3801 # ConsistentMap Exceptions
3802 assert "org.onosproject.store.service" not in output
3803 # Node not leader
3804 assert "java.lang.IllegalStateException" not in output
3805 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003806 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003807 "command: " + str( output ) )
3808 retryTime = 30 # Conservative time, given by Madan
3809 main.log.info( "Waiting " + str( retryTime ) +
3810 "seconds before retrying." )
3811 time.sleep( retryTime ) # Due to change in mastership
3812 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003813 assert "Command not found:" not in output, output
3814 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003815 main.log.info( self.name + ": " + output )
3816
3817 if length == 0:
3818 match = re.search( pattern, output )
3819 else: # if given values
3820 if length == 1: # Contains output
3821 patternTrue = pattern + "\n" + containsTrue
3822 patternFalse = pattern + "\n" + containsFalse
3823 else: # ContainsAll output
3824 patternTrue = pattern + "\n" + containsAllTrue
3825 patternFalse = pattern + "\n" + containsAllFalse
3826 matchTrue = re.search( patternTrue, output )
3827 matchFalse = re.search( patternFalse, output )
3828 if matchTrue:
3829 containsCheck = main.TRUE
3830 match = matchTrue
3831 elif matchFalse:
3832 containsCheck = main.FALSE
3833 match = matchFalse
3834 else:
3835 main.log.error( self.name + " setTestGet did not match " +\
3836 "expected output" )
3837 main.log.debug( self.name + " expected: " + pattern )
3838 main.log.debug( self.name + " actual: " + repr( output ) )
3839 match = None
3840 if match:
3841 setMatch = match.group( 1 )
3842 if setMatch == '':
3843 setList = []
3844 else:
3845 setList = setMatch.split( ", " )
3846 if length > 0:
3847 return ( setList, containsCheck )
3848 else:
3849 return setList
3850 else: # no match
3851 main.log.error( self.name + ": setTestGet did not" +
3852 " match expected output" )
3853 main.log.debug( self.name + " expected: " + pattern )
3854 main.log.debug( self.name + " actual: " + repr( output ) )
3855 return main.ERROR
3856 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003857 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003858 return main.ERROR
3859 except TypeError:
3860 main.log.exception( self.name + ": Object not as expected" )
3861 return main.ERROR
3862 except pexpect.EOF:
3863 main.log.error( self.name + ": EOF exception found" )
3864 main.log.error( self.name + ": " + self.handle.before )
3865 main.cleanup()
3866 main.exit()
3867 except Exception:
3868 main.log.exception( self.name + ": Uncaught exception!" )
3869 main.cleanup()
3870 main.exit()
3871
3872 def setTestSize( self, setName ):
3873 """
3874 CLI command to get the elements in a distributed set.
3875 Required arguments:
3876 setName - The name of the set to remove from.
3877 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003878 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003879 None on error
3880 """
3881 try:
3882 # TODO: Should this check against the number of elements returned
3883 # and then return true/false based on that?
3884 setName = str( setName ).strip()
3885 # Patterns to match
3886 setPattern = "\[(.*)\]"
3887 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3888 setPattern
3889 cmdStr = "set-test-get -s "
3890 cmdStr += setName
3891 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003892 try:
3893 # TODO: Maybe make this less hardcoded
3894 # ConsistentMap Exceptions
3895 assert "org.onosproject.store.service" not in output
3896 # Node not leader
3897 assert "java.lang.IllegalStateException" not in output
3898 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003899 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003900 "command: " + str( output ) )
3901 retryTime = 30 # Conservative time, given by Madan
3902 main.log.info( "Waiting " + str( retryTime ) +
3903 "seconds before retrying." )
3904 time.sleep( retryTime ) # Due to change in mastership
3905 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003906 assert "Command not found:" not in output, output
3907 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003908 main.log.info( self.name + ": " + output )
3909 match = re.search( pattern, output )
3910 if match:
3911 setSize = int( match.group( 1 ) )
3912 setMatch = match.group( 2 )
3913 if len( setMatch.split() ) == setSize:
3914 main.log.info( "The size returned by " + self.name +
3915 " matches the number of elements in " +
3916 "the returned set" )
3917 else:
3918 main.log.error( "The size returned by " + self.name +
3919 " does not match the number of " +
3920 "elements in the returned set." )
3921 return setSize
3922 else: # no match
3923 main.log.error( self.name + ": setTestGet did not" +
3924 " match expected output" )
3925 main.log.debug( self.name + " expected: " + pattern )
3926 main.log.debug( self.name + " actual: " + repr( output ) )
3927 return None
3928 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003929 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003930 return None
Jon Hall390696c2015-05-05 17:13:41 -07003931 except TypeError:
3932 main.log.exception( self.name + ": Object not as expected" )
3933 return None
3934 except pexpect.EOF:
3935 main.log.error( self.name + ": EOF exception found" )
3936 main.log.error( self.name + ": " + self.handle.before )
3937 main.cleanup()
3938 main.exit()
3939 except Exception:
3940 main.log.exception( self.name + ": Uncaught exception!" )
3941 main.cleanup()
3942 main.exit()
3943
Jon Hall80daded2015-05-27 16:07:00 -07003944 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003945 """
3946 Command to list the various counters in the system.
3947 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003948 if jsonFormat, a string of the json object returned by the cli
3949 command
3950 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003951 None on error
3952 """
Jon Hall390696c2015-05-05 17:13:41 -07003953 try:
3954 counters = {}
3955 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003956 if jsonFormat:
3957 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003958 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003959 assert "Command not found:" not in output, output
3960 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003961 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003962 return output
Jon Hall390696c2015-05-05 17:13:41 -07003963 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003964 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003965 return None
Jon Hall390696c2015-05-05 17:13:41 -07003966 except TypeError:
3967 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003968 return None
Jon Hall390696c2015-05-05 17:13:41 -07003969 except pexpect.EOF:
3970 main.log.error( self.name + ": EOF exception found" )
3971 main.log.error( self.name + ": " + self.handle.before )
3972 main.cleanup()
3973 main.exit()
3974 except Exception:
3975 main.log.exception( self.name + ": Uncaught exception!" )
3976 main.cleanup()
3977 main.exit()
3978
Jon Halle1a3b752015-07-22 13:02:46 -07003979 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003980 """
Jon Halle1a3b752015-07-22 13:02:46 -07003981 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003982 Required arguments:
3983 counter - The name of the counter to increment.
3984 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003985 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003986 inMemory - use in memory map for the counter
3987 returns:
3988 integer value of the counter or
3989 None on Error
3990 """
3991 try:
3992 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003993 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003994 cmdStr = "counter-test-increment "
3995 if inMemory:
3996 cmdStr += "-i "
3997 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003998 if delta != 1:
3999 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004000 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004001 try:
4002 # TODO: Maybe make this less hardcoded
4003 # ConsistentMap Exceptions
4004 assert "org.onosproject.store.service" not in output
4005 # Node not leader
4006 assert "java.lang.IllegalStateException" not in output
4007 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004008 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004009 "command: " + str( output ) )
4010 retryTime = 30 # Conservative time, given by Madan
4011 main.log.info( "Waiting " + str( retryTime ) +
4012 "seconds before retrying." )
4013 time.sleep( retryTime ) # Due to change in mastership
4014 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004015 assert "Command not found:" not in output, output
4016 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004017 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004018 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004019 match = re.search( pattern, output )
4020 if match:
4021 return int( match.group( 1 ) )
4022 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004023 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004024 " match expected output." )
4025 main.log.debug( self.name + " expected: " + pattern )
4026 main.log.debug( self.name + " actual: " + repr( output ) )
4027 return None
4028 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004029 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004030 return None
4031 except TypeError:
4032 main.log.exception( self.name + ": Object not as expected" )
4033 return None
4034 except pexpect.EOF:
4035 main.log.error( self.name + ": EOF exception found" )
4036 main.log.error( self.name + ": " + self.handle.before )
4037 main.cleanup()
4038 main.exit()
4039 except Exception:
4040 main.log.exception( self.name + ": Uncaught exception!" )
4041 main.cleanup()
4042 main.exit()
4043
Jon Halle1a3b752015-07-22 13:02:46 -07004044 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4045 """
4046 CLI command to get a distributed counter then add a delta to it.
4047 Required arguments:
4048 counter - The name of the counter to increment.
4049 Optional arguments:
4050 delta - The long to add to the counter
4051 inMemory - use in memory map for the counter
4052 returns:
4053 integer value of the counter or
4054 None on Error
4055 """
4056 try:
4057 counter = str( counter )
4058 delta = int( delta )
4059 cmdStr = "counter-test-increment -g "
4060 if inMemory:
4061 cmdStr += "-i "
4062 cmdStr += counter
4063 if delta != 1:
4064 cmdStr += " " + str( delta )
4065 output = self.sendline( cmdStr )
4066 try:
4067 # TODO: Maybe make this less hardcoded
4068 # ConsistentMap Exceptions
4069 assert "org.onosproject.store.service" not in output
4070 # Node not leader
4071 assert "java.lang.IllegalStateException" not in output
4072 except AssertionError:
4073 main.log.error( "Error in processing '" + cmdStr + "' " +
4074 "command: " + str( output ) )
4075 retryTime = 30 # Conservative time, given by Madan
4076 main.log.info( "Waiting " + str( retryTime ) +
4077 "seconds before retrying." )
4078 time.sleep( retryTime ) # Due to change in mastership
4079 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004080 assert "Command not found:" not in output, output
4081 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004082 main.log.info( self.name + ": " + output )
4083 pattern = counter + " was updated to (-?\d+)"
4084 match = re.search( pattern, output )
4085 if match:
4086 return int( match.group( 1 ) )
4087 else:
4088 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4089 " match expected output." )
4090 main.log.debug( self.name + " expected: " + pattern )
4091 main.log.debug( self.name + " actual: " + repr( output ) )
4092 return None
4093 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004094 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004095 return None
4096 except TypeError:
4097 main.log.exception( self.name + ": Object not as expected" )
4098 return None
4099 except pexpect.EOF:
4100 main.log.error( self.name + ": EOF exception found" )
4101 main.log.error( self.name + ": " + self.handle.before )
4102 main.cleanup()
4103 main.exit()
4104 except Exception:
4105 main.log.exception( self.name + ": Uncaught exception!" )
4106 main.cleanup()
4107 main.exit()
4108
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004109 def summary( self, jsonFormat=True ):
4110 """
4111 Description: Execute summary command in onos
4112 Returns: json object ( summary -j ), returns main.FALSE if there is
4113 no output
4114
4115 """
4116 try:
4117 cmdStr = "summary"
4118 if jsonFormat:
4119 cmdStr += " -j"
4120 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004121 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004122 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004123 if not handle:
4124 main.log.error( self.name + ": There is no output in " +
4125 "summary command" )
4126 return main.FALSE
4127 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004128 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004129 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004130 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004131 except TypeError:
4132 main.log.exception( self.name + ": Object not as expected" )
4133 return None
4134 except pexpect.EOF:
4135 main.log.error( self.name + ": EOF exception found" )
4136 main.log.error( self.name + ": " + self.handle.before )
4137 main.cleanup()
4138 main.exit()
4139 except Exception:
4140 main.log.exception( self.name + ": Uncaught exception!" )
4141 main.cleanup()
4142 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004143
4144 def transactionalMapGet( self, keyName, inMemory=False ):
4145 """
4146 CLI command to get the value of a key in a consistent map using
4147 transactions. This a test function and can only get keys from the
4148 test map hard coded into the cli command
4149 Required arguments:
4150 keyName - The name of the key to get
4151 Optional arguments:
4152 inMemory - use in memory map for the counter
4153 returns:
4154 The string value of the key or
4155 None on Error
4156 """
4157 try:
4158 keyName = str( keyName )
4159 cmdStr = "transactional-map-test-get "
4160 if inMemory:
4161 cmdStr += "-i "
4162 cmdStr += keyName
4163 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004164 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004165 try:
4166 # TODO: Maybe make this less hardcoded
4167 # ConsistentMap Exceptions
4168 assert "org.onosproject.store.service" not in output
4169 # Node not leader
4170 assert "java.lang.IllegalStateException" not in output
4171 except AssertionError:
4172 main.log.error( "Error in processing '" + cmdStr + "' " +
4173 "command: " + str( output ) )
4174 return None
4175 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4176 if "Key " + keyName + " not found." in output:
4177 return None
4178 else:
4179 match = re.search( pattern, output )
4180 if match:
4181 return match.groupdict()[ 'value' ]
4182 else:
4183 main.log.error( self.name + ": transactionlMapGet did not" +
4184 " match expected output." )
4185 main.log.debug( self.name + " expected: " + pattern )
4186 main.log.debug( self.name + " actual: " + repr( output ) )
4187 return None
Jon Hallc6793552016-01-19 14:18:37 -08004188 except AssertionError:
4189 main.log.exception( "" )
4190 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004191 except TypeError:
4192 main.log.exception( self.name + ": Object not as expected" )
4193 return None
4194 except pexpect.EOF:
4195 main.log.error( self.name + ": EOF exception found" )
4196 main.log.error( self.name + ": " + self.handle.before )
4197 main.cleanup()
4198 main.exit()
4199 except Exception:
4200 main.log.exception( self.name + ": Uncaught exception!" )
4201 main.cleanup()
4202 main.exit()
4203
4204 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4205 """
4206 CLI command to put a value into 'numKeys' number of keys in a
4207 consistent map using transactions. This a test function and can only
4208 put into keys named 'Key#' of the test map hard coded into the cli command
4209 Required arguments:
4210 numKeys - Number of keys to add the value to
4211 value - The string value to put into the keys
4212 Optional arguments:
4213 inMemory - use in memory map for the counter
4214 returns:
4215 A dictionary whose keys are the name of the keys put into the map
4216 and the values of the keys are dictionaries whose key-values are
4217 'value': value put into map and optionaly
4218 'oldValue': Previous value in the key or
4219 None on Error
4220
4221 Example output
4222 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4223 'Key2': {'value': 'Testing'} }
4224 """
4225 try:
4226 numKeys = str( numKeys )
4227 value = str( value )
4228 cmdStr = "transactional-map-test-put "
4229 if inMemory:
4230 cmdStr += "-i "
4231 cmdStr += numKeys + " " + value
4232 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004233 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004234 try:
4235 # TODO: Maybe make this less hardcoded
4236 # ConsistentMap Exceptions
4237 assert "org.onosproject.store.service" not in output
4238 # Node not leader
4239 assert "java.lang.IllegalStateException" not in output
4240 except AssertionError:
4241 main.log.error( "Error in processing '" + cmdStr + "' " +
4242 "command: " + str( output ) )
4243 return None
4244 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4245 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4246 results = {}
4247 for line in output.splitlines():
4248 new = re.search( newPattern, line )
4249 updated = re.search( updatedPattern, line )
4250 if new:
4251 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4252 elif updated:
4253 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004254 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004255 else:
4256 main.log.error( self.name + ": transactionlMapGet did not" +
4257 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004258 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4259 newPattern,
4260 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004261 main.log.debug( self.name + " actual: " + repr( output ) )
4262 return results
Jon Hallc6793552016-01-19 14:18:37 -08004263 except AssertionError:
4264 main.log.exception( "" )
4265 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004266 except TypeError:
4267 main.log.exception( self.name + ": Object not as expected" )
4268 return None
4269 except pexpect.EOF:
4270 main.log.error( self.name + ": EOF exception found" )
4271 main.log.error( self.name + ": " + self.handle.before )
4272 main.cleanup()
4273 main.exit()
4274 except Exception:
4275 main.log.exception( self.name + ": Uncaught exception!" )
4276 main.cleanup()
4277 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004278
acsmarsdaea66c2015-09-03 11:44:06 -07004279 def maps( self, jsonFormat=True ):
4280 """
4281 Description: Returns result of onos:maps
4282 Optional:
4283 * jsonFormat: enable json formatting of output
4284 """
4285 try:
4286 cmdStr = "maps"
4287 if jsonFormat:
4288 cmdStr += " -j"
4289 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004290 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004291 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004292 except AssertionError:
4293 main.log.exception( "" )
4294 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004295 except TypeError:
4296 main.log.exception( self.name + ": Object not as expected" )
4297 return None
4298 except pexpect.EOF:
4299 main.log.error( self.name + ": EOF exception found" )
4300 main.log.error( self.name + ": " + self.handle.before )
4301 main.cleanup()
4302 main.exit()
4303 except Exception:
4304 main.log.exception( self.name + ": Uncaught exception!" )
4305 main.cleanup()
4306 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004307
4308 def getSwController( self, uri, jsonFormat=True ):
4309 """
4310 Descrition: Gets the controller information from the device
4311 """
4312 try:
4313 cmd = "device-controllers "
4314 if jsonFormat:
4315 cmd += "-j "
4316 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004317 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004318 return response
Jon Hallc6793552016-01-19 14:18:37 -08004319 except AssertionError:
4320 main.log.exception( "" )
4321 return None
GlennRC050596c2015-11-18 17:06:41 -08004322 except TypeError:
4323 main.log.exception( self.name + ": Object not as expected" )
4324 return None
4325 except pexpect.EOF:
4326 main.log.error( self.name + ": EOF exception found" )
4327 main.log.error( self.name + ": " + self.handle.before )
4328 main.cleanup()
4329 main.exit()
4330 except Exception:
4331 main.log.exception( self.name + ": Uncaught exception!" )
4332 main.cleanup()
4333 main.exit()
4334
4335 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4336 """
4337 Descrition: sets the controller(s) for the specified device
4338
4339 Parameters:
4340 Required: uri - String: The uri of the device(switch).
4341 ip - String or List: The ip address of the controller.
4342 This parameter can be formed in a couple of different ways.
4343 VALID:
4344 10.0.0.1 - just the ip address
4345 tcp:10.0.0.1 - the protocol and the ip address
4346 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4347 so that you can add controllers with different
4348 protocols and ports
4349 INVALID:
4350 10.0.0.1:6653 - this is not supported by ONOS
4351
4352 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4353 port - The port number.
4354 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4355
4356 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4357 """
4358 try:
4359 cmd = "device-setcontrollers"
4360
4361 if jsonFormat:
4362 cmd += " -j"
4363 cmd += " " + uri
4364 if isinstance( ip, str ):
4365 ip = [ip]
4366 for item in ip:
4367 if ":" in item:
4368 sitem = item.split( ":" )
4369 if len(sitem) == 3:
4370 cmd += " " + item
4371 elif "." in sitem[1]:
4372 cmd += " {}:{}".format(item, port)
4373 else:
4374 main.log.error( "Malformed entry: " + item )
4375 raise TypeError
4376 else:
4377 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004378 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004379 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004380 if "Error" in response:
4381 main.log.error( response )
4382 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004383 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004384 except AssertionError:
4385 main.log.exception( "" )
4386 return None
GlennRC050596c2015-11-18 17:06:41 -08004387 except TypeError:
4388 main.log.exception( self.name + ": Object not as expected" )
4389 return main.FALSE
4390 except pexpect.EOF:
4391 main.log.error( self.name + ": EOF exception found" )
4392 main.log.error( self.name + ": " + self.handle.before )
4393 main.cleanup()
4394 main.exit()
4395 except Exception:
4396 main.log.exception( self.name + ": Uncaught exception!" )
4397 main.cleanup()
4398 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004399
4400 def removeDevice( self, device ):
4401 '''
4402 Description:
4403 Remove a device from ONOS by passing the uri of the device(s).
4404 Parameters:
4405 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4406 Returns:
4407 Returns main.FALSE if an exception is thrown or an error is present
4408 in the response. Otherwise, returns main.TRUE.
4409 NOTE:
4410 If a host cannot be removed, then this function will return main.FALSE
4411 '''
4412 try:
4413 if type( device ) is str:
4414 device = list( device )
4415
4416 for d in device:
4417 time.sleep( 1 )
4418 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004419 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004420 if "Error" in response:
4421 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4422 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004423 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004424 except AssertionError:
4425 main.log.exception( "" )
4426 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004427 except TypeError:
4428 main.log.exception( self.name + ": Object not as expected" )
4429 return main.FALSE
4430 except pexpect.EOF:
4431 main.log.error( self.name + ": EOF exception found" )
4432 main.log.error( self.name + ": " + self.handle.before )
4433 main.cleanup()
4434 main.exit()
4435 except Exception:
4436 main.log.exception( self.name + ": Uncaught exception!" )
4437 main.cleanup()
4438 main.exit()
4439
4440 def removeHost( self, host ):
4441 '''
4442 Description:
4443 Remove a host from ONOS by passing the id of the host(s)
4444 Parameters:
4445 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4446 Returns:
4447 Returns main.FALSE if an exception is thrown or an error is present
4448 in the response. Otherwise, returns main.TRUE.
4449 NOTE:
4450 If a host cannot be removed, then this function will return main.FALSE
4451 '''
4452 try:
4453 if type( host ) is str:
4454 host = list( host )
4455
4456 for h in host:
4457 time.sleep( 1 )
4458 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004459 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004460 if "Error" in response:
4461 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4462 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004463 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004464 except AssertionError:
4465 main.log.exception( "" )
4466 return None
GlennRC20fc6522015-12-23 23:26:57 -08004467 except TypeError:
4468 main.log.exception( self.name + ": Object not as expected" )
4469 return main.FALSE
4470 except pexpect.EOF:
4471 main.log.error( self.name + ": EOF exception found" )
4472 main.log.error( self.name + ": " + self.handle.before )
4473 main.cleanup()
4474 main.exit()
4475 except Exception:
4476 main.log.exception( self.name + ": Uncaught exception!" )
4477 main.cleanup()
4478 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004479
Jon Hallc6793552016-01-19 14:18:37 -08004480 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004481 '''
4482 Description:
4483 Bring link down or up in the null-provider.
4484 params:
4485 begin - (string) One end of a device or switch.
4486 end - (string) the other end of the device or switch
4487 returns:
4488 main.TRUE if no exceptions were thrown and no Errors are
4489 present in the resoponse. Otherwise, returns main.FALSE
4490 '''
4491 try:
Jon Hallc6793552016-01-19 14:18:37 -08004492 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004493 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004494 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004495 if "Error" in response or "Failure" in response:
4496 main.log.error( response )
4497 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004498 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004499 except AssertionError:
4500 main.log.exception( "" )
4501 return None
GlennRCed771242016-01-13 17:02:47 -08004502 except TypeError:
4503 main.log.exception( self.name + ": Object not as expected" )
4504 return main.FALSE
4505 except pexpect.EOF:
4506 main.log.error( self.name + ": EOF exception found" )
4507 main.log.error( self.name + ": " + self.handle.before )
4508 main.cleanup()
4509 main.exit()
4510 except Exception:
4511 main.log.exception( self.name + ": Uncaught exception!" )
4512 main.cleanup()
4513 main.exit()
4514