blob: e4e810720d721ec4294e90707448d1dae1aed4e2 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1: # not in CLI
148 return main.TRUE
149 elif i == 3: # Timeout
150 return main.FALSE
151 else:
andrewonlab9627f432014-11-14 12:45:10 -0500152 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700158 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500159 main.cleanup()
160 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700161 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700162 main.log.error( self.name +
163 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 main.cleanup()
167 main.exit()
168
kelvin-onlabd3b64892015-01-20 13:26:24 -0800169 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab95ce8322014-10-13 14:12:04 -0400171 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800172
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800174 """
andrewonlab95ce8322014-10-13 14:12:04 -0400175 try:
176 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 main.cleanup()
179 main.exit()
180 else:
kelvin8ec71442015-01-15 16:57:00 -0800181 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800183 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400184 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800185 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800188 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800189 self.handle.sendline("")
190 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800191 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400195
196 return main.TRUE
197
Jon Halld4d4b372015-01-28 16:02:41 -0800198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400204 main.cleanup()
205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400208 main.cleanup()
209 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800210
pingping-lin57a56ce2015-05-20 16:43:48 -0700211 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800212 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
Jon Hallefbd9792015-03-05 16:11:36 -0800214 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800217 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800220
Hari Krishna25d42f72015-01-05 15:08:28 -0800221 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800223
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800226 """
You Wangf69ab392016-01-26 16:34:38 -0800227 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400228 try:
kelvin8ec71442015-01-15 16:57:00 -0800229 self.handle.sendline( "" )
230 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700231 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500232
233 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800234 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500235 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400236
kelvin8ec71442015-01-15 16:57:00 -0800237 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800239 i = self.handle.expect( [
240 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700241 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400242
243 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800244 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800245 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800246 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800247 "config:property-set -p org.apache.karaf.shell\
248 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800249 karafTimeout )
250 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400253 return main.TRUE
254 else:
kelvin8ec71442015-01-15 16:57:00 -0800255 # If failed, send ctrl+c to process and try again
256 main.log.info( "Starting CLI failed. Retrying..." )
257 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800259 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
260 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400261 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800263 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800264 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 "config:property-set -p org.apache.karaf.shell\
267 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800268 karafTimeout )
269 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800270 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800271 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400272 return main.TRUE
273 else:
kelvin8ec71442015-01-15 16:57:00 -0800274 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400276 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400277
Jon Halld4d4b372015-01-28 16:02:41 -0800278 except TypeError:
279 main.log.exception( self.name + ": Object not as expected" )
280 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400281 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800282 main.log.error( self.name + ": EOF exception found" )
283 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400284 main.cleanup()
285 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800286 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800287 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400288 main.cleanup()
289 main.exit()
290
Jon Hallefbd9792015-03-05 16:11:36 -0800291 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800292 """
293 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800294 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800295 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800296 Available level: DEBUG, TRACE, INFO, WARN, ERROR
297 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800298 """
299 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800300 lvlStr = ""
301 if level:
302 lvlStr = "--level=" + level
303
kelvin-onlab9f541032015-02-04 16:19:53 -0800304 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800305 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700306 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800307 main.log.error( self.name + ": onos cli session closed. ")
308 if self.onosIp:
309 main.log.warn( "Trying to reconnect " + self.onosIp )
310 reconnectResult = self.startOnosCli( self.onosIp )
311 if reconnectResult:
312 main.log.info( self.name + ": onos cli session reconnected." )
313 else:
314 main.log.error( self.name + ": reconnection failed." )
315 main.cleanup()
316 main.exit()
317 else:
318 main.cleanup()
319 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700320 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700321 self.handle.sendline( "" )
322 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800323 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700324 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800325 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800326
kelvin-onlab9f541032015-02-04 16:19:53 -0800327 response = self.handle.before
328 if re.search( "Error", response ):
329 return main.FALSE
330 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700331 except pexpect.TIMEOUT:
332 main.log.exception( self.name + ": TIMEOUT exception found" )
333 main.cleanup()
334 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800335 except pexpect.EOF:
336 main.log.error( self.name + ": EOF exception found" )
337 main.log.error( self.name + ": " + self.handle.before )
338 main.cleanup()
339 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800340 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800341 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400342 main.cleanup()
343 main.exit()
344
GlennRCed771242016-01-13 17:02:47 -0800345 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800346 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800347 Send a completely user specified string to
348 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400349 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800350
andrewonlaba18f6bf2014-10-13 19:31:54 -0400351 Warning: There are no sanity checking to commands
352 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800353
kelvin8ec71442015-01-15 16:57:00 -0800354 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400355 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800356 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
357 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800359 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800360 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800361 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800362 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
363 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700365 main.log.debug( self.name + ": Raw output" )
366 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700367
368 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800369 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800370 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700372 main.log.debug( self.name + ": ansiEscape output" )
373 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700374
kelvin-onlabfb521662015-02-27 09:52:40 -0800375 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800376 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700377 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700378 main.log.debug( self.name + ": Removed extra returns " +
379 "from output" )
380 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700381
382 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800383 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700384 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700385 main.log.debug( self.name + ": parsed and stripped output" )
386 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700387
Jon Hall63604932015-02-26 17:09:50 -0800388 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700389 output = response.split( cmdStr.strip(), 1 )
390 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700391 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700392 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700393 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800394 output = output[1].strip()
395 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800396 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800397 return output
GlennRCed771242016-01-13 17:02:47 -0800398 except pexpect.TIMEOUT:
399 main.log.error( self.name + ":ONOS timeout" )
400 if debug:
401 main.log.debug( self.handle.before )
402 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700403 except IndexError:
404 main.log.exception( self.name + ": Object not as expected" )
405 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400412 main.cleanup()
413 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400416 main.cleanup()
417 main.exit()
418
kelvin8ec71442015-01-15 16:57:00 -0800419 # IMPORTANT NOTE:
420 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 # the cli command changing 'a:b' with 'aB'.
422 # Ex ) onos:topology > onosTopology
423 # onos:links > onosLinks
424 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800425
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800427 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400428 Adds a new cluster node by ID and address information.
429 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 * nodeId
431 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800434 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800436 cmdStr = "add-node " + str( nodeId ) + " " +\
437 str( ONOSIp ) + " " + str( tcpPort )
438 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800439 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800440 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( "Error in adding node" )
442 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800443 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800445 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800447 except AssertionError:
448 main.log.exception( "" )
449 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800450 except TypeError:
451 main.log.exception( self.name + ": Object not as expected" )
452 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( self.name + ": EOF exception found" )
455 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400456 main.cleanup()
457 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800459 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400460 main.cleanup()
461 main.exit()
462
kelvin-onlabd3b64892015-01-20 13:26:24 -0800463 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
andrewonlab86dc3082014-10-13 18:18:38 -0400465 Removes a cluster by ID
466 Issues command: 'remove-node [<node-id>]'
467 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800469 """
andrewonlab86dc3082014-10-13 18:18:38 -0400470 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400471
kelvin-onlabd3b64892015-01-20 13:26:24 -0800472 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700473 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800474 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700475 if re.search( "Error", handle ):
476 main.log.error( "Error in removing node" )
477 main.log.error( handle )
478 return main.FALSE
479 else:
480 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800481 except AssertionError:
482 main.log.exception( "" )
483 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800484 except TypeError:
485 main.log.exception( self.name + ": Object not as expected" )
486 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400487 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800488 main.log.error( self.name + ": EOF exception found" )
489 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400490 main.cleanup()
491 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800493 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400494 main.cleanup()
495 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400496
Jon Hall61282e32015-03-19 11:34:11 -0700497 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800498 """
andrewonlab7c211572014-10-15 16:45:20 -0400499 List the nodes currently visible
500 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700501 Optional argument:
502 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlab7c211572014-10-15 16:45:20 -0400504 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700506 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 cmdStr += " -j"
508 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800509 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700510 return output
Jon Hallc6793552016-01-19 14:18:37 -0800511 except AssertionError:
512 main.log.exception( "" )
513 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800514 except TypeError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
andrewonlab7c211572014-10-15 16:45:20 -0400517 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800518 main.log.error( self.name + ": EOF exception found" )
519 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400520 main.cleanup()
521 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800522 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800523 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400524 main.cleanup()
525 main.exit()
526
kelvin8ec71442015-01-15 16:57:00 -0800527 def topology( self ):
528 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700529 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700530 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700531 Return:
532 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800533 """
andrewonlab95ce8322014-10-13 14:12:04 -0400534 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700535 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800536 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800537 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400539 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800540 except AssertionError:
541 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800542 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800543 except TypeError:
544 main.log.exception( self.name + ": Object not as expected" )
545 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400546 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800547 main.log.error( self.name + ": EOF exception found" )
548 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400549 main.cleanup()
550 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800551 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800552 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 main.cleanup()
554 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800555
jenkins7ead5a82015-03-13 10:28:21 -0700556 def deviceRemove( self, deviceId ):
557 """
558 Removes particular device from storage
559
560 TODO: refactor this function
561 """
562 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700563 cmdStr = "device-remove " + str( deviceId )
564 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800565 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 if re.search( "Error", handle ):
567 main.log.error( "Error in removing device" )
568 main.log.error( handle )
569 return main.FALSE
570 else:
571 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800572 except AssertionError:
573 main.log.exception( "" )
574 return None
jenkins7ead5a82015-03-13 10:28:21 -0700575 except TypeError:
576 main.log.exception( self.name + ": Object not as expected" )
577 return None
578 except pexpect.EOF:
579 main.log.error( self.name + ": EOF exception found" )
580 main.log.error( self.name + ": " + self.handle.before )
581 main.cleanup()
582 main.exit()
583 except Exception:
584 main.log.exception( self.name + ": Uncaught exception!" )
585 main.cleanup()
586 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700587
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800589 """
Jon Hall7b02d952014-10-17 20:14:54 -0400590 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400591 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800593 """
andrewonlab86dc3082014-10-13 18:18:38 -0400594 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 cmdStr += " -j"
598 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800599 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700600 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800601 except AssertionError:
602 main.log.exception( "" )
603 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800604 except TypeError:
605 main.log.exception( self.name + ": Object not as expected" )
606 return None
andrewonlab7c211572014-10-15 16:45:20 -0400607 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800608 main.log.error( self.name + ": EOF exception found" )
609 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400610 main.cleanup()
611 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800612 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800613 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400614 main.cleanup()
615 main.exit()
616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800619 This balances the devices across all controllers
620 by issuing command: 'onos> onos:balance-masters'
621 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800622 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800623 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700625 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800626 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700627 if re.search( "Error", handle ):
628 main.log.error( "Error in balancing masters" )
629 main.log.error( handle )
630 return main.FALSE
631 else:
632 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800633 except AssertionError:
634 main.log.exception( "" )
635 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800636 except TypeError:
637 main.log.exception( self.name + ": Object not as expected" )
638 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( self.name + ": EOF exception found" )
641 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800642 main.cleanup()
643 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800644 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800645 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800646 main.cleanup()
647 main.exit()
648
Jon Hallc6793552016-01-19 14:18:37 -0800649 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700650 """
651 Returns the output of the masters command.
652 Optional argument:
653 * jsonFormat - boolean indicating if you want output in json
654 """
655 try:
656 cmdStr = "onos:masters"
657 if jsonFormat:
658 cmdStr += " -j"
659 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800660 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700661 return output
Jon Hallc6793552016-01-19 14:18:37 -0800662 except AssertionError:
663 main.log.exception( "" )
664 return None
acsmars24950022015-07-30 18:00:43 -0700665 except TypeError:
666 main.log.exception( self.name + ": Object not as expected" )
667 return None
668 except pexpect.EOF:
669 main.log.error( self.name + ": EOF exception found" )
670 main.log.error( self.name + ": " + self.handle.before )
671 main.cleanup()
672 main.exit()
673 except Exception:
674 main.log.exception( self.name + ": Uncaught exception!" )
675 main.cleanup()
676 main.exit()
677
Jon Hallc6793552016-01-19 14:18:37 -0800678 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700679 """
680 Uses the master command to check that the devices' leadership
681 is evenly divided
682
683 Dependencies: checkMasters() and summary()
684
685 Returns main.True if the devices are balanced
686 Returns main.False if the devices are unbalanced
687 Exits on Exception
688 Returns None on TypeError
689 """
690 try:
Jon Hallc6793552016-01-19 14:18:37 -0800691 summaryOutput = self.summary()
692 totalDevices = json.loads( summaryOutput )[ "devices" ]
693 except ( TypeError, ValueError ):
694 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
695 return None
696 try:
acsmars24950022015-07-30 18:00:43 -0700697 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800698 mastersOutput = self.checkMasters()
699 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700700 first = masters[ 0 ][ "size" ]
701 for master in masters:
702 totalOwnedDevices += master[ "size" ]
703 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
704 main.log.error( "Mastership not balanced" )
705 main.log.info( "\n" + self.checkMasters( False ) )
706 return main.FALSE
707 main.log.info( "Mastership balanced between " \
708 + str( len(masters) ) + " masters" )
709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800710 except ( TypeError, ValueError ):
711 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700712 return None
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
716 main.cleanup()
717 main.exit()
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
720 main.cleanup()
721 main.exit()
722
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800724 """
Jon Halle8217482014-10-17 13:49:14 -0400725 Lists all core links
726 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800728 """
Jon Halle8217482014-10-17 13:49:14 -0400729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 cmdStr += " -j"
733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800736 except AssertionError:
737 main.log.exception( "" )
738 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800739 except TypeError:
740 main.log.exception( self.name + ": Object not as expected" )
741 return None
Jon Halle8217482014-10-17 13:49:14 -0400742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800743 main.log.error( self.name + ": EOF exception found" )
744 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400745 main.cleanup()
746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800748 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Jon Halle8217482014-10-17 13:49:14 -0400754 Lists all ports
755 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800756 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Jon Halle8217482014-10-17 13:49:14 -0400758 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700759 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700761 cmdStr += " -j"
762 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800763 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700764 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800765 except AssertionError:
766 main.log.exception( "" )
767 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800768 except TypeError:
769 main.log.exception( self.name + ": Object not as expected" )
770 return None
Jon Halle8217482014-10-17 13:49:14 -0400771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400774 main.cleanup()
775 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800776 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800777 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400778 main.cleanup()
779 main.exit()
780
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800782 """
Jon Hall983a1702014-10-28 18:44:22 -0400783 Lists all devices and the controllers with roles assigned to them
784 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800786 """
andrewonlab7c211572014-10-15 16:45:20 -0400787 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700788 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800789 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700790 cmdStr += " -j"
791 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800792 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800794 except AssertionError:
795 main.log.exception( "" )
796 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800797 except TypeError:
798 main.log.exception( self.name + ": Object not as expected" )
799 return None
Jon Hall983a1702014-10-28 18:44:22 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400803 main.cleanup()
804 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800805 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800806 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400807 main.cleanup()
808 main.exit()
809
kelvin-onlabd3b64892015-01-20 13:26:24 -0800810 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800811 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800812 Given the a string containing the json representation of the "roles"
813 cli command and a partial or whole device id, returns a json object
814 containing the roles output for the first device whose id contains
815 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400816
817 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800818 A dict of the role assignments for the given device or
819 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800820 """
Jon Hall983a1702014-10-28 18:44:22 -0400821 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400823 return None
824 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 rawRoles = self.roles()
826 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800827 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800829 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800830 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400831 return device
832 return None
Jon Hallc6793552016-01-19 14:18:37 -0800833 except ( TypeError, ValueError ):
834 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800835 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400836 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800837 main.log.error( self.name + ": EOF exception found" )
838 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400839 main.cleanup()
840 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800842 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400843 main.cleanup()
844 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800845
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Hall94fd0472014-12-08 11:52:42 -0800848 Iterates through each device and checks if there is a master assigned
849 Returns: main.TRUE if each device has a master
850 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800851 """
Jon Hall94fd0472014-12-08 11:52:42 -0800852 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 rawRoles = self.roles()
854 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800855 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800857 # print device
858 if device[ 'master' ] == "none":
859 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800860 return main.FALSE
861 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800862 except ( TypeError, ValueError ):
863 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800864 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800868 main.cleanup()
869 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800870 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800871 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800872 main.cleanup()
873 main.exit()
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400877 Returns string of paths, and the cost.
878 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800879 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400880 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
882 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800883 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800884 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800885 main.log.error( "Error in getting paths" )
886 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400887 else:
kelvin8ec71442015-01-15 16:57:00 -0800888 path = handle.split( ";" )[ 0 ]
889 cost = handle.split( ";" )[ 1 ]
890 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800891 except AssertionError:
892 main.log.exception( "" )
893 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800894 except TypeError:
895 main.log.exception( self.name + ": Object not as expected" )
896 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400897 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( self.name + ": EOF exception found" )
899 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400900 main.cleanup()
901 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800902 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800903 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400904 main.cleanup()
905 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800906
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Hallffb386d2014-11-21 13:43:38 -0800909 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400910 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800912 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400913 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700914 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 cmdStr += " -j"
917 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800918 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800919 try:
920 # TODO: Maybe make this less hardcoded
921 # ConsistentMap Exceptions
922 assert "org.onosproject.store.service" not in handle
923 # Node not leader
924 assert "java.lang.IllegalStateException" not in handle
925 except AssertionError:
926 main.log.error( "Error in processing '" + cmdStr + "' " +
927 "command: " + str( handle ) )
928 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400939 main.cleanup()
940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400943 main.cleanup()
944 main.exit()
945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800947 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400948 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800949
Jon Hallefbd9792015-03-05 16:11:36 -0800950 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800951 partial mac address
952
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800954 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400955 try:
kelvin8ec71442015-01-15 16:57:00 -0800956 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400957 return None
958 else:
959 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800960 rawHosts = self.hosts()
961 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800962 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800964 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800965 if not host:
966 pass
967 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400968 return host
969 return None
Jon Hallc6793552016-01-19 14:18:37 -0800970 except ( TypeError, ValueError ):
971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800972 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400973 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800974 main.log.error( self.name + ": EOF exception found" )
975 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400976 main.cleanup()
977 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800979 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400980 main.cleanup()
981 main.exit()
982
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800984 """
985 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400986 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800987
andrewonlab3f0a4af2014-10-17 12:25:14 -0400988 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400990 IMPORTANT:
991 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800992 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400993 Furthermore, it assumes that value of VLAN is '-1'
994 Description:
kelvin8ec71442015-01-15 16:57:00 -0800995 Converts mininet hosts ( h1, h2, h3... ) into
996 ONOS format ( 00:00:00:00:00:01/-1 , ... )
997 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001002 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 hostHex = hex( int( host ) ).zfill( 12 )
1004 hostHex = str( hostHex ).replace( 'x', '0' )
1005 i = iter( str( hostHex ) )
1006 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1007 hostHex = hostHex + "/-1"
1008 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001009
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001011
Jon Halld4d4b372015-01-28 16:02:41 -08001012 except TypeError:
1013 main.log.exception( self.name + ": Object not as expected" )
1014 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001015 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001016 main.log.error( self.name + ": EOF exception found" )
1017 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001018 main.cleanup()
1019 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001020 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001021 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001022 main.cleanup()
1023 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001024
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001026 """
andrewonlabe6745342014-10-17 14:29:13 -04001027 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 * hostIdOne: ONOS host id for host1
1029 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001030 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001031 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001032 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001033 Returns:
1034 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlabe6745342014-10-17 14:29:13 -04001036 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1038 " " + str( hostIdTwo )
1039 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001040 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001041 if re.search( "Error", handle ):
1042 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001043 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001044 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001045 else:
1046 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001047 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1048 match = re.search('id=0x([\da-f]+),', handle)
1049 if match:
1050 return match.group()[3:-1]
1051 else:
1052 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001053 main.log.debug( "Response from ONOS was: " +
1054 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001055 return None
Jon Hallc6793552016-01-19 14:18:37 -08001056 except AssertionError:
1057 main.log.exception( "" )
1058 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001059 except TypeError:
1060 main.log.exception( self.name + ": Object not as expected" )
1061 return None
andrewonlabe6745342014-10-17 14:29:13 -04001062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001063 main.log.error( self.name + ": EOF exception found" )
1064 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001065 main.cleanup()
1066 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001067 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001068 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001069 main.cleanup()
1070 main.exit()
1071
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001073 """
andrewonlab7b31d232014-10-24 13:31:47 -04001074 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 * ingressDevice: device id of ingress device
1076 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001077 Optional:
1078 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001079 Description:
1080 Adds an optical intent by specifying an ingress and egress device
1081 Returns:
1082 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001083 """
andrewonlab7b31d232014-10-24 13:31:47 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1086 " " + str( egressDevice )
1087 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001088 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001089 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 main.log.error( "Error in adding Optical intent" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001094 main.log.info( "Optical intent installed between " +
1095 str( ingressDevice ) + " and " +
1096 str( egressDevice ) )
1097 match = re.search('id=0x([\da-f]+),', handle)
1098 if match:
1099 return match.group()[3:-1]
1100 else:
1101 main.log.error( "Error, intent ID not found" )
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except AssertionError:
1104 main.log.exception( "" )
1105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001106 except TypeError:
1107 main.log.exception( self.name + ": Object not as expected" )
1108 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( self.name + ": EOF exception found" )
1111 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001112 main.cleanup()
1113 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001114 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001115 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001116 main.cleanup()
1117 main.exit()
1118
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001120 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001121 ingressDevice,
1122 egressDevice,
1123 portIngress="",
1124 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001125 ethType="",
1126 ethSrc="",
1127 ethDst="",
1128 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001130 ipProto="",
1131 ipSrc="",
1132 ipDst="",
1133 tcpSrc="",
1134 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001136 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 * ingressDevice: device id of ingress device
1138 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001139 Optional:
1140 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001141 * ethSrc: specify ethSrc ( i.e. src mac addr )
1142 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001143 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001145 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001146 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001147 * ipSrc: specify ip source address
1148 * ipDst: specify ip destination address
1149 * tcpSrc: specify tcp source port
1150 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001151 Description:
kelvin8ec71442015-01-15 16:57:00 -08001152 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001153 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001154 Returns:
1155 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001156
Jon Halle3f39ff2015-01-13 11:50:53 -08001157 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001158 options developers provide for point-to-point
1159 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001160 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001161 try:
kelvin8ec71442015-01-15 16:57:00 -08001162 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001163 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001165 and not ipProto and not ipSrc and not ipDst \
1166 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001167 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001168
andrewonlab289e4b72014-10-21 21:24:18 -04001169 else:
andrewonlab36af3822014-11-18 17:48:18 -05001170 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001171
andrewonlab0c0a6772014-10-22 12:31:18 -04001172 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001173 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001174 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --ethSrc " + str( ethSrc )
1176 if ethDst:
1177 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001178 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 cmd += " --lambda "
1182 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001184 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001186 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001188 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001190 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001191 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001192
kelvin8ec71442015-01-15 16:57:00 -08001193 # Check whether the user appended the port
1194 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if "/" in ingressDevice:
1196 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001197 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001199 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001200 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001201 # Would it make sense to throw an exception and exit
1202 # the test?
1203 return None
andrewonlab36af3822014-11-18 17:48:18 -05001204
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 str( ingressDevice ) + "/" +\
1207 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001208
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if "/" in egressDevice:
1210 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001211 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001213 main.log.error( "You must specify the egress port" )
1214 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001215
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001217 str( egressDevice ) + "/" +\
1218 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001219
kelvin-onlab898a6c62015-01-16 14:13:53 -08001220 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001221 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001222 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001225 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001226 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001227 # TODO: print out all the options in this message?
1228 main.log.info( "Point-to-point intent installed between " +
1229 str( ingressDevice ) + " and " +
1230 str( egressDevice ) )
1231 match = re.search('id=0x([\da-f]+),', handle)
1232 if match:
1233 return match.group()[3:-1]
1234 else:
1235 main.log.error( "Error, intent ID not found" )
1236 return None
Jon Hallc6793552016-01-19 14:18:37 -08001237 except AssertionError:
1238 main.log.exception( "" )
1239 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001240 except TypeError:
1241 main.log.exception( self.name + ": Object not as expected" )
1242 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.error( self.name + ": EOF exception found" )
1245 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001246 main.cleanup()
1247 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001248 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001249 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001250 main.cleanup()
1251 main.exit()
1252
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001254 self,
shahshreyac2f97072015-03-19 17:04:29 -07001255 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001257 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 ethType="",
1260 ethSrc="",
1261 ethDst="",
1262 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 ipProto="",
1265 ipSrc="",
1266 ipDst="",
1267 tcpSrc="",
1268 tcpDst="",
1269 setEthSrc="",
1270 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001271 """
shahshreyad0c80432014-12-04 16:56:05 -08001272 Note:
shahshreya70622b12015-03-19 17:19:00 -07001273 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001274 is same. That is, all ingress devices include port numbers
1275 with a "/" or all ingress devices could specify device
1276 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001277 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001278 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001279 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
1293 * setEthSrc: action to Rewrite Source MAC Address
1294 * setEthDst: action to Rewrite Destination MAC Address
1295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001302 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
shahshreyad0c80432014-12-04 16:56:05 -08001305 try:
kelvin8ec71442015-01-15 16:57:00 -08001306 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001307 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001308 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001309 and not ipProto and not ipSrc and not ipDst\
1310 and not tcpSrc and not tcpDst and not setEthSrc\
1311 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001312 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001313
1314 else:
1315 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001316
shahshreyad0c80432014-12-04 16:56:05 -08001317 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001318 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001319 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001320 cmd += " --ethSrc " + str( ethSrc )
1321 if ethDst:
1322 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001323 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001324 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001326 cmd += " --lambda "
1327 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001329 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001330 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001331 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001332 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001333 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001334 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001335 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001336 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001337 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001339 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001341
kelvin8ec71442015-01-15 16:57:00 -08001342 # Check whether the user appended the port
1343 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001344
1345 if portIngressList is None:
1346 for ingressDevice in ingressDeviceList:
1347 if "/" in ingressDevice:
1348 cmd += " " + str( ingressDevice )
1349 else:
1350 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001351 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001352 # TODO: perhaps more meaningful return
1353 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001354 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001355 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001356 for ingressDevice, portIngress in zip( ingressDeviceList,
1357 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001358 cmd += " " + \
1359 str( ingressDevice ) + "/" +\
1360 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001361 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001362 main.log.error( "Device list and port list does not " +
1363 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001364 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if "/" in egressDevice:
1366 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001367 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001369 main.log.error( "You must specify " +
1370 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001371 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001372
kelvin8ec71442015-01-15 16:57:00 -08001373 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001374 str( egressDevice ) + "/" +\
1375 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001377 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001379 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 main.log.error( "Error in adding multipoint-to-singlepoint " +
1381 "intent" )
1382 return None
shahshreyad0c80432014-12-04 16:56:05 -08001383 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001384 match = re.search('id=0x([\da-f]+),', handle)
1385 if match:
1386 return match.group()[3:-1]
1387 else:
1388 main.log.error( "Error, intent ID not found" )
1389 return None
Jon Hallc6793552016-01-19 14:18:37 -08001390 except AssertionError:
1391 main.log.exception( "" )
1392 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001393 except TypeError:
1394 main.log.exception( self.name + ": Object not as expected" )
1395 return None
1396 except pexpect.EOF:
1397 main.log.error( self.name + ": EOF exception found" )
1398 main.log.error( self.name + ": " + self.handle.before )
1399 main.cleanup()
1400 main.exit()
1401 except Exception:
1402 main.log.exception( self.name + ": Uncaught exception!" )
1403 main.cleanup()
1404 main.exit()
1405
1406 def addSinglepointToMultipointIntent(
1407 self,
1408 ingressDevice,
1409 egressDeviceList,
1410 portIngress="",
1411 portEgressList=None,
1412 ethType="",
1413 ethSrc="",
1414 ethDst="",
1415 bandwidth="",
1416 lambdaAlloc=False,
1417 ipProto="",
1418 ipSrc="",
1419 ipDst="",
1420 tcpSrc="",
1421 tcpDst="",
1422 setEthSrc="",
1423 setEthDst="" ):
1424 """
1425 Note:
1426 This function assumes the format of all egress devices
1427 is same. That is, all egress devices include port numbers
1428 with a "/" or all egress devices could specify device
1429 ids and port numbers seperately.
1430 Required:
1431 * EgressDeviceList: List of device ids of egress device
1432 ( Atleast 2 eress devices required in the list )
1433 * ingressDevice: device id of ingress device
1434 Optional:
1435 * ethType: specify ethType
1436 * ethSrc: specify ethSrc ( i.e. src mac addr )
1437 * ethDst: specify ethDst ( i.e. dst mac addr )
1438 * bandwidth: specify bandwidth capacity of link
1439 * lambdaAlloc: if True, intent will allocate lambda
1440 for the specified intent
1441 * ipProto: specify ip protocol
1442 * ipSrc: specify ip source address
1443 * ipDst: specify ip destination address
1444 * tcpSrc: specify tcp source port
1445 * tcpDst: specify tcp destination port
1446 * setEthSrc: action to Rewrite Source MAC Address
1447 * setEthDst: action to Rewrite Destination MAC Address
1448 Description:
1449 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1450 specifying device id's and optional fields
1451 Returns:
1452 A string of the intent id or None on error
1453
1454 NOTE: This function may change depending on the
1455 options developers provide for singlepoint-to-multipoint
1456 intent via cli
1457 """
1458 try:
1459 # If there are no optional arguments
1460 if not ethType and not ethSrc and not ethDst\
1461 and not bandwidth and not lambdaAlloc\
1462 and not ipProto and not ipSrc and not ipDst\
1463 and not tcpSrc and not tcpDst and not setEthSrc\
1464 and not setEthDst:
1465 cmd = "add-single-to-multi-intent"
1466
1467 else:
1468 cmd = "add-single-to-multi-intent"
1469
1470 if ethType:
1471 cmd += " --ethType " + str( ethType )
1472 if ethSrc:
1473 cmd += " --ethSrc " + str( ethSrc )
1474 if ethDst:
1475 cmd += " --ethDst " + str( ethDst )
1476 if bandwidth:
1477 cmd += " --bandwidth " + str( bandwidth )
1478 if lambdaAlloc:
1479 cmd += " --lambda "
1480 if ipProto:
1481 cmd += " --ipProto " + str( ipProto )
1482 if ipSrc:
1483 cmd += " --ipSrc " + str( ipSrc )
1484 if ipDst:
1485 cmd += " --ipDst " + str( ipDst )
1486 if tcpSrc:
1487 cmd += " --tcpSrc " + str( tcpSrc )
1488 if tcpDst:
1489 cmd += " --tcpDst " + str( tcpDst )
1490 if setEthSrc:
1491 cmd += " --setEthSrc " + str( setEthSrc )
1492 if setEthDst:
1493 cmd += " --setEthDst " + str( setEthDst )
1494
1495 # Check whether the user appended the port
1496 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001497
kelvin-onlabb9408212015-04-01 13:34:04 -07001498 if "/" in ingressDevice:
1499 cmd += " " + str( ingressDevice )
1500 else:
1501 if not portIngress:
1502 main.log.error( "You must specify " +
1503 "the Ingress port" )
1504 return main.FALSE
1505
1506 cmd += " " +\
1507 str( ingressDevice ) + "/" +\
1508 str( portIngress )
1509
1510 if portEgressList is None:
1511 for egressDevice in egressDeviceList:
1512 if "/" in egressDevice:
1513 cmd += " " + str( egressDevice )
1514 else:
1515 main.log.error( "You must specify " +
1516 "the egress port" )
1517 # TODO: perhaps more meaningful return
1518 return main.FALSE
1519 else:
1520 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001521 for egressDevice, portEgress in zip( egressDeviceList,
1522 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001523 cmd += " " + \
1524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001526 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001527 main.log.error( "Device list and port list does not " +
1528 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001529 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001530 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001531 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001532 # If error, return error message
1533 if re.search( "Error", handle ):
1534 main.log.error( "Error in adding singlepoint-to-multipoint " +
1535 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001536 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001537 else:
1538 match = re.search('id=0x([\da-f]+),', handle)
1539 if match:
1540 return match.group()[3:-1]
1541 else:
1542 main.log.error( "Error, intent ID not found" )
1543 return None
Jon Hallc6793552016-01-19 14:18:37 -08001544 except AssertionError:
1545 main.log.exception( "" )
1546 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001547 except TypeError:
1548 main.log.exception( self.name + ": Object not as expected" )
1549 return None
shahshreyad0c80432014-12-04 16:56:05 -08001550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001551 main.log.error( self.name + ": EOF exception found" )
1552 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001553 main.cleanup()
1554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001556 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001557 main.cleanup()
1558 main.exit()
1559
Hari Krishna9e232602015-04-13 17:29:08 -07001560 def addMplsIntent(
1561 self,
1562 ingressDevice,
1563 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001564 ingressPort="",
1565 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001566 ethType="",
1567 ethSrc="",
1568 ethDst="",
1569 bandwidth="",
1570 lambdaAlloc=False,
1571 ipProto="",
1572 ipSrc="",
1573 ipDst="",
1574 tcpSrc="",
1575 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001576 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001577 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001578 priority=""):
1579 """
1580 Required:
1581 * ingressDevice: device id of ingress device
1582 * egressDevice: device id of egress device
1583 Optional:
1584 * ethType: specify ethType
1585 * ethSrc: specify ethSrc ( i.e. src mac addr )
1586 * ethDst: specify ethDst ( i.e. dst mac addr )
1587 * bandwidth: specify bandwidth capacity of link
1588 * lambdaAlloc: if True, intent will allocate lambda
1589 for the specified intent
1590 * ipProto: specify ip protocol
1591 * ipSrc: specify ip source address
1592 * ipDst: specify ip destination address
1593 * tcpSrc: specify tcp source port
1594 * tcpDst: specify tcp destination port
1595 * ingressLabel: Ingress MPLS label
1596 * egressLabel: Egress MPLS label
1597 Description:
1598 Adds MPLS intent by
1599 specifying device id's and optional fields
1600 Returns:
1601 A string of the intent id or None on error
1602
1603 NOTE: This function may change depending on the
1604 options developers provide for MPLS
1605 intent via cli
1606 """
1607 try:
1608 # If there are no optional arguments
1609 if not ethType and not ethSrc and not ethDst\
1610 and not bandwidth and not lambdaAlloc \
1611 and not ipProto and not ipSrc and not ipDst \
1612 and not tcpSrc and not tcpDst and not ingressLabel \
1613 and not egressLabel:
1614 cmd = "add-mpls-intent"
1615
1616 else:
1617 cmd = "add-mpls-intent"
1618
1619 if ethType:
1620 cmd += " --ethType " + str( ethType )
1621 if ethSrc:
1622 cmd += " --ethSrc " + str( ethSrc )
1623 if ethDst:
1624 cmd += " --ethDst " + str( ethDst )
1625 if bandwidth:
1626 cmd += " --bandwidth " + str( bandwidth )
1627 if lambdaAlloc:
1628 cmd += " --lambda "
1629 if ipProto:
1630 cmd += " --ipProto " + str( ipProto )
1631 if ipSrc:
1632 cmd += " --ipSrc " + str( ipSrc )
1633 if ipDst:
1634 cmd += " --ipDst " + str( ipDst )
1635 if tcpSrc:
1636 cmd += " --tcpSrc " + str( tcpSrc )
1637 if tcpDst:
1638 cmd += " --tcpDst " + str( tcpDst )
1639 if ingressLabel:
1640 cmd += " --ingressLabel " + str( ingressLabel )
1641 if egressLabel:
1642 cmd += " --egressLabel " + str( egressLabel )
1643 if priority:
1644 cmd += " --priority " + str( priority )
1645
1646 # Check whether the user appended the port
1647 # or provided it as an input
1648 if "/" in ingressDevice:
1649 cmd += " " + str( ingressDevice )
1650 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001651 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001652 main.log.error( "You must specify the ingress port" )
1653 return None
1654
1655 cmd += " " + \
1656 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001657 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001658
1659 if "/" in egressDevice:
1660 cmd += " " + str( egressDevice )
1661 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001662 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001663 main.log.error( "You must specify the egress port" )
1664 return None
1665
1666 cmd += " " +\
1667 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001668 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001669
1670 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001671 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001672 # If error, return error message
1673 if re.search( "Error", handle ):
1674 main.log.error( "Error in adding mpls intent" )
1675 return None
1676 else:
1677 # TODO: print out all the options in this message?
1678 main.log.info( "MPLS intent installed between " +
1679 str( ingressDevice ) + " and " +
1680 str( egressDevice ) )
1681 match = re.search('id=0x([\da-f]+),', handle)
1682 if match:
1683 return match.group()[3:-1]
1684 else:
1685 main.log.error( "Error, intent ID not found" )
1686 return None
Jon Hallc6793552016-01-19 14:18:37 -08001687 except AssertionError:
1688 main.log.exception( "" )
1689 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001690 except TypeError:
1691 main.log.exception( self.name + ": Object not as expected" )
1692 return None
1693 except pexpect.EOF:
1694 main.log.error( self.name + ": EOF exception found" )
1695 main.log.error( self.name + ": " + self.handle.before )
1696 main.cleanup()
1697 main.exit()
1698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
1700 main.cleanup()
1701 main.exit()
1702
Jon Hallefbd9792015-03-05 16:11:36 -08001703 def removeIntent( self, intentId, app='org.onosproject.cli',
1704 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001705 """
shahshreya1c818fc2015-02-26 13:44:08 -08001706 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001707 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001708 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001709 -p or --purge: Purge the intent from the store after removal
1710
Jon Halle3f39ff2015-01-13 11:50:53 -08001711 Returns:
1712 main.False on error and
1713 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001714 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001715 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001716 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001717 if purge:
1718 cmdStr += " -p"
1719 if sync:
1720 cmdStr += " -s"
1721
1722 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001724 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001725 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001726 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001727 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001728 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001729 # TODO: Should this be main.TRUE
1730 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001731 except AssertionError:
1732 main.log.exception( "" )
1733 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001734 except TypeError:
1735 main.log.exception( self.name + ": Object not as expected" )
1736 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001737 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001738 main.log.error( self.name + ": EOF exception found" )
1739 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001740 main.cleanup()
1741 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001743 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001744 main.cleanup()
1745 main.exit()
1746
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001747 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001748 """
1749 Purges all WITHDRAWN Intents
1750 """
1751 try:
1752 cmdStr = "purge-intents"
1753 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001754 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001755 if re.search( "Error", handle ):
1756 main.log.error( "Error in purging intents" )
1757 return main.FALSE
1758 else:
1759 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001760 except AssertionError:
1761 main.log.exception( "" )
1762 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001763 except TypeError:
1764 main.log.exception( self.name + ": Object not as expected" )
1765 return None
1766 except pexpect.EOF:
1767 main.log.error( self.name + ": EOF exception found" )
1768 main.log.error( self.name + ": " + self.handle.before )
1769 main.cleanup()
1770 main.exit()
1771 except Exception:
1772 main.log.exception( self.name + ": Uncaught exception!" )
1773 main.cleanup()
1774 main.exit()
1775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001777 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 NOTE: This method should be used after installing application:
1779 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001780 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001782 Description:
1783 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001784 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001785 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001786 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001787 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001788 cmdStr += " -j"
1789 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001790 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001791 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001792 except AssertionError:
1793 main.log.exception( "" )
1794 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001795 except TypeError:
1796 main.log.exception( self.name + ": Object not as expected" )
1797 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001798 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001799 main.log.error( self.name + ": EOF exception found" )
1800 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001801 main.cleanup()
1802 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001804 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001805 main.cleanup()
1806 main.exit()
1807
pingping-lin54b03372015-08-13 14:43:10 -07001808 def ipv4RouteNumber( self ):
1809 """
1810 NOTE: This method should be used after installing application:
1811 onos-app-sdnip
1812 Description:
1813 Obtain the total IPv4 routes number in the system
1814 """
1815 try:
1816 cmdStr = "routes -s -j"
1817 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001818 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001819 jsonResult = json.loads( handle )
1820 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001821 except AssertionError:
1822 main.log.exception( "" )
1823 return None
1824 except ( TypeError, ValueError ):
1825 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001826 return None
1827 except pexpect.EOF:
1828 main.log.error( self.name + ": EOF exception found" )
1829 main.log.error( self.name + ": " + self.handle.before )
1830 main.cleanup()
1831 main.exit()
1832 except Exception:
1833 main.log.exception( self.name + ": Uncaught exception!" )
1834 main.cleanup()
1835 main.exit()
1836
pingping-lin8244a3b2015-09-16 13:36:56 -07001837 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001838 """
andrewonlabe6745342014-10-17 14:29:13 -04001839 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001840 Obtain intents from the ONOS cli.
1841 Optional:
1842 * jsonFormat: Enable output formatting in json, default to True
1843 * summary: Whether only output the intent summary, defaults to False
1844 * type: Only output a certain type of intent. This options is valid
1845 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 """
andrewonlabe6745342014-10-17 14:29:13 -04001847 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001848 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001849 if summary:
1850 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001852 cmdStr += " -j"
1853 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001854 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001855 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001856 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001857 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001858 else:
Jon Hallff566d52016-01-15 14:45:36 -08001859 intentType = ""
1860 # IF we want the summary of a specific intent type
1861 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001862 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001863 if intentType in jsonResult.keys():
1864 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001865 else:
Jon Hallff566d52016-01-15 14:45:36 -08001866 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001867 return handle
1868 else:
Jon Hallff566d52016-01-15 14:45:36 -08001869 main.log.error( handle )
pingping-lin8244a3b2015-09-16 13:36:56 -07001870 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001871 except AssertionError:
1872 main.log.exception( "" )
1873 return None
1874 except ( TypeError, ValueError ):
1875 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001876 return None
1877 except pexpect.EOF:
1878 main.log.error( self.name + ": EOF exception found" )
1879 main.log.error( self.name + ": " + self.handle.before )
1880 main.cleanup()
1881 main.exit()
1882 except Exception:
1883 main.log.exception( self.name + ": Uncaught exception!" )
1884 main.cleanup()
1885 main.exit()
1886
kelvin-onlab54400a92015-02-26 18:05:51 -08001887 def getIntentState(self, intentsId, intentsJson=None):
1888 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001889 Check intent state.
1890 Accepts a single intent ID (string type) or a list of intent IDs.
1891 Returns the state(string type) of the id if a single intent ID is
1892 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001893 Returns a dictionary with intent IDs as the key and its
1894 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001895 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001896 intentId: intent ID (string type)
1897 intentsJson: parsed json object from the onos:intents api
1898 Returns:
1899 state = An intent's state- INSTALL,WITHDRAWN etc.
1900 stateDict = Dictionary of intent's state. intent ID as the keys and
1901 state as the values.
1902 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001903 try:
1904 state = "State is Undefined"
1905 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001906 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001907 else:
Jon Hallc6793552016-01-19 14:18:37 -08001908 rawJson = intentsJson
1909 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001910 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001911 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001912 if intentsId == intent[ 'id' ]:
1913 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001914 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001915 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1916 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001917 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001918 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001919 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001920 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001921 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001922 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001923 if intentsId[ i ] == intents[ 'id' ]:
1924 stateDict[ 'state' ] = intents[ 'state' ]
1925 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001926 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001927 break
Jon Hallefbd9792015-03-05 16:11:36 -08001928 if len( intentsId ) != len( dictList ):
1929 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001930 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001931 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001932 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001933 return None
Jon Hallc6793552016-01-19 14:18:37 -08001934 except ( TypeError, ValueError ):
1935 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001936 return None
1937 except pexpect.EOF:
1938 main.log.error( self.name + ": EOF exception found" )
1939 main.log.error( self.name + ": " + self.handle.before )
1940 main.cleanup()
1941 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001942 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001943 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001944 main.cleanup()
1945 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001946
kelvin-onlabf512e942015-06-08 19:42:59 -07001947 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001948 """
1949 Description:
1950 Check intents state
1951 Required:
1952 intentsId - List of intents ID to be checked
1953 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001954 expectedState - Check the expected state(s) of each intents
1955 state in the list.
1956 *NOTE: You can pass in a list of expected state,
1957 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001958 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001959 Returns main.TRUE only if all intent are the same as expected states
1960 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001961 """
1962 try:
1963 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001964 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001965 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001966 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08001967 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001968 "getting intents state" )
1969 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001970
1971 if isinstance( expectedState, types.StringType ):
1972 for intents in intentsDict:
1973 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001974 main.log.debug( self.name + " : Intent ID - " +
1975 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001976 " actual state = " +
1977 intents.get( 'state' )
1978 + " does not equal expected state = "
1979 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001980 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001981
1982 elif isinstance( expectedState, types.ListType ):
1983 for intents in intentsDict:
1984 if not any( state == intents.get( 'state' ) for state in
1985 expectedState ):
1986 main.log.debug( self.name + " : Intent ID - " +
1987 intents.get( 'id' ) +
1988 " actual state = " +
1989 intents.get( 'state' ) +
1990 " does not equal expected states = "
1991 + str( expectedState ) )
1992 returnValue = main.FALSE
1993
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001994 if returnValue == main.TRUE:
1995 main.log.info( self.name + ": All " +
1996 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001997 " intents are in " + str( expectedState ) +
1998 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001999 return returnValue
2000 except TypeError:
2001 main.log.exception( self.name + ": Object not as expected" )
2002 return None
2003 except pexpect.EOF:
2004 main.log.error( self.name + ": EOF exception found" )
2005 main.log.error( self.name + ": " + self.handle.before )
2006 main.cleanup()
2007 main.exit()
2008 except Exception:
2009 main.log.exception( self.name + ": Uncaught exception!" )
2010 main.cleanup()
2011 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002012
GlennRCed771242016-01-13 17:02:47 -08002013 def checkIntentSummary( self, timeout=60 ):
2014 """
2015 Description:
2016 Check the number of installed intents.
2017 Optional:
2018 timeout - the timeout for pexcept
2019 Return:
2020 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2021 , otherwise, returns main.FALSE.
2022 """
2023
2024 try:
2025 cmd = "intents -s -j"
2026
2027 # Check response if something wrong
2028 response = self.sendline( cmd, timeout=timeout )
2029 if response == None:
2030 return main.False
2031 response = json.loads( response )
2032
2033 # get total and installed number, see if they are match
2034 allState = response.get( 'all' )
2035 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002036 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002037 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002038 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002039 return main.FALSE
2040
Jon Hallc6793552016-01-19 14:18:37 -08002041 except ( TypeError, ValueError ):
2042 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002043 return None
2044 except pexpect.EOF:
2045 main.log.error( self.name + ": EOF exception found" )
2046 main.log.error( self.name + ": " + self.handle.before )
2047 main.cleanup()
2048 main.exit()
2049 except Exception:
2050 main.log.exception( self.name + ": Uncaught exception!" )
2051 main.cleanup()
2052 main.exit()
2053
2054 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002055 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002056 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002057 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002058 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002059 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002060 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002061 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002062 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002063 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002064 cmdStr += " -j "
2065 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002066 handle = self.sendline( cmdStr, timeout=timeout )
2067 assert "Command not found:" not in handle, handle
2068 if re.search( "Error:", handle ):
2069 main.log.error( self.name + ": flows() response: " +
2070 str( handle ) )
2071 return handle
2072 except AssertionError:
2073 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002074 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002075 except TypeError:
2076 main.log.exception( self.name + ": Object not as expected" )
2077 return None
Jon Hallc6793552016-01-19 14:18:37 -08002078 except pexpect.TIMEOUT:
2079 main.log.error( self.name + ": ONOS timeout" )
2080 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002081 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002082 main.log.error( self.name + ": EOF exception found" )
2083 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002084 main.cleanup()
2085 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002086 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002087 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002088 main.cleanup()
2089 main.exit()
2090
GlennRCed771242016-01-13 17:02:47 -08002091
Jon Hallc6793552016-01-19 14:18:37 -08002092 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002093 """
2094 Description:
GlennRCed771242016-01-13 17:02:47 -08002095 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002096 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2097 if the count of those states is 0, which means all current flows
2098 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002099 Optional:
GlennRCed771242016-01-13 17:02:47 -08002100 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002101 Return:
2102 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002103 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002104 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002105 """
2106 try:
GlennRCed771242016-01-13 17:02:47 -08002107 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2108 checkedStates = []
2109 statesCount = [0, 0, 0, 0]
2110 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002111 rawFlows = self.flows( state=s, timeout = timeout )
2112 checkedStates.append( json.loads( rawFlows ) )
2113 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002114 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002115 try:
2116 statesCount[i] += int( c.get( "flowCount" ) )
2117 except TypeError:
2118 main.log.exception( "Json object not as expected" )
2119 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002120
GlennRCed771242016-01-13 17:02:47 -08002121 # We want to count PENDING_ADD if isPENDING is true
2122 if isPENDING:
2123 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2124 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002125 else:
GlennRCed771242016-01-13 17:02:47 -08002126 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2127 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002128 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002129 except ( TypeError, ValueError ):
2130 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002131 return None
2132 except pexpect.EOF:
2133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
2135 main.cleanup()
2136 main.exit()
2137 except Exception:
2138 main.log.exception( self.name + ": Uncaught exception!" )
2139 main.cleanup()
2140 main.exit()
2141
GlennRCed771242016-01-13 17:02:47 -08002142 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2143 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002144 """
andrewonlab87852b02014-11-19 18:44:19 -05002145 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002146 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002147 a specific point-to-point intent definition
2148 Required:
GlennRCed771242016-01-13 17:02:47 -08002149 * ingress: specify source dpid
2150 * egress: specify destination dpid
2151 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002152 Optional:
GlennRCed771242016-01-13 17:02:47 -08002153 * offset: the keyOffset is where the next batch of intents
2154 will be installed
2155 Returns: If failed to push test intents, it will returen None,
2156 if successful, return true.
2157 Timeout expection will return None,
2158 TypeError will return false
2159 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002160 """
andrewonlab87852b02014-11-19 18:44:19 -05002161 try:
GlennRCed771242016-01-13 17:02:47 -08002162 if background:
2163 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002164 else:
GlennRCed771242016-01-13 17:02:47 -08002165 back = ""
2166 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002167 ingress,
2168 egress,
2169 batchSize,
2170 offset,
2171 back )
GlennRCed771242016-01-13 17:02:47 -08002172 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002173 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002174 main.log.info( response )
2175 if response == None:
2176 return None
2177
2178 # TODO: We should handle if there is failure in installation
2179 return main.TRUE
2180
Jon Hallc6793552016-01-19 14:18:37 -08002181 except AssertionError:
2182 main.log.exception( "" )
2183 return None
GlennRCed771242016-01-13 17:02:47 -08002184 except pexpect.TIMEOUT:
2185 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002186 return None
andrewonlab87852b02014-11-19 18:44:19 -05002187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002190 main.cleanup()
2191 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002192 except TypeError:
2193 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002194 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002196 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002197 main.cleanup()
2198 main.exit()
2199
YPZhangf6f14a02016-01-28 15:17:31 -08002200 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002201 """
2202 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002203 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002204 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002205 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002206 """
YPZhange3109a72016-02-02 11:25:37 -08002207
YPZhangb5d3f832016-01-23 22:54:26 -08002208 try:
YPZhange3109a72016-02-02 11:25:37 -08002209 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002210 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002211 totalFlows = self.sendline( cmd, timeout=timeout )
2212
2213 if totalFlows == None:
2214 # if timeout, we will get total number of all flows, and subtract other states
2215 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2216 checkedStates = []
2217 totalFlows = 0
2218 statesCount = [0, 0, 0, 0]
2219
2220 # get total flows from summary
2221 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2222 totalFlows = int( response.get("flows") )
2223
2224 for s in states:
2225 rawFlows = self.flows( state=s, timeout = timeout )
2226 if rawFlows == None:
2227 # if timeout, return the total flows number from summary command
2228 return totalFlows
2229 checkedStates.append( json.loads( rawFlows ) )
2230
2231 # Calculate ADDED flows number, equal total subtracts others
2232 for i in range( len( states ) ):
2233 for c in checkedStates[i]:
2234 try:
2235 statesCount[i] += int( c.get( "flowCount" ) )
2236 except TypeError:
2237 main.log.exception( "Json object not as expected" )
2238 totalFlows = totalFlows - int( statesCount[i] )
2239 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2240
2241 return totalFlows
2242
2243 return totalFlows
2244
YPZhangb5d3f832016-01-23 22:54:26 -08002245 except TypeError:
2246 main.log.exception( self.name + ": Object not as expected" )
2247 return None
2248 except pexpect.EOF:
2249 main.log.error( self.name + ": EOF exception found" )
2250 main.log.error( self.name + ": " + self.handle.before )
2251 main.cleanup()
2252 main.exit()
2253 except Exception:
2254 main.log.exception( self.name + ": Uncaught exception!" )
2255 main.cleanup()
2256 main.exit()
2257
2258 def getTotalIntentsNum( self ):
2259 """
2260 Description:
2261 Get the total number of intents, include every states.
2262 Return:
2263 The number of intents
2264 """
2265 try:
2266 cmd = "summary -j"
2267 response = self.sendline( cmd )
2268 if response == None:
2269 return -1
2270 response = json.loads( response )
2271 return int( response.get("intents") )
2272 except TypeError:
2273 main.log.exception( self.name + ": Object not as expected" )
2274 return None
2275 except pexpect.EOF:
2276 main.log.error( self.name + ": EOF exception found" )
2277 main.log.error( self.name + ": " + self.handle.before )
2278 main.cleanup()
2279 main.exit()
2280 except Exception:
2281 main.log.exception( self.name + ": Uncaught exception!" )
2282 main.cleanup()
2283 main.exit()
2284
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002286 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002287 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002288 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002290 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002291 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002292 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002293 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002294 cmdStr += " -j"
2295 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002296 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002297 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002298 except AssertionError:
2299 main.log.exception( "" )
2300 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002301 except TypeError:
2302 main.log.exception( self.name + ": Object not as expected" )
2303 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002305 main.log.error( self.name + ": EOF exception found" )
2306 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002307 main.cleanup()
2308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002310 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002311 main.cleanup()
2312 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002313
kelvin-onlabd3b64892015-01-20 13:26:24 -08002314 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002315 """
2316 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002317 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002318 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002319 """
andrewonlab867212a2014-10-22 20:13:38 -04002320 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002321 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002323 cmdStr += " -j"
2324 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002325 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002326 if handle:
2327 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002328 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002329 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002330 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002331 else:
2332 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002333 except AssertionError:
2334 main.log.exception( "" )
2335 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002336 except TypeError:
2337 main.log.exception( self.name + ": Object not as expected" )
2338 return None
andrewonlab867212a2014-10-22 20:13:38 -04002339 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002340 main.log.error( self.name + ": EOF exception found" )
2341 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002342 main.cleanup()
2343 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002344 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002345 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002346 main.cleanup()
2347 main.exit()
2348
kelvin8ec71442015-01-15 16:57:00 -08002349 # Wrapper functions ****************
2350 # Wrapper functions use existing driver
2351 # functions and extends their use case.
2352 # For example, we may use the output of
2353 # a normal driver function, and parse it
2354 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002355
kelvin-onlabd3b64892015-01-20 13:26:24 -08002356 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002357 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002358 Description:
2359 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002360 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002361 try:
kelvin8ec71442015-01-15 16:57:00 -08002362 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002363 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002364 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002365
kelvin8ec71442015-01-15 16:57:00 -08002366 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002367 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2368 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002369 match = re.search('id=0x([\da-f]+),', intents)
2370 if match:
2371 tmpId = match.group()[3:-1]
2372 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002373 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002374
Jon Halld4d4b372015-01-28 16:02:41 -08002375 except TypeError:
2376 main.log.exception( self.name + ": Object not as expected" )
2377 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002378 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002379 main.log.error( self.name + ": EOF exception found" )
2380 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002381 main.cleanup()
2382 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002383 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002384 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002385 main.cleanup()
2386 main.exit()
2387
Jon Hall30b82fa2015-03-04 17:15:43 -08002388 def FlowAddedCount( self, deviceId ):
2389 """
2390 Determine the number of flow rules for the given device id that are
2391 in the added state
2392 """
2393 try:
2394 cmdStr = "flows any " + str( deviceId ) + " | " +\
2395 "grep 'state=ADDED' | wc -l"
2396 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002397 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002398 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002399 except AssertionError:
2400 main.log.exception( "" )
2401 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002402 except pexpect.EOF:
2403 main.log.error( self.name + ": EOF exception found" )
2404 main.log.error( self.name + ": " + self.handle.before )
2405 main.cleanup()
2406 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002407 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002408 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002409 main.cleanup()
2410 main.exit()
2411
kelvin-onlabd3b64892015-01-20 13:26:24 -08002412 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002413 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002414 Use 'devices' function to obtain list of all devices
2415 and parse the result to obtain a list of all device
2416 id's. Returns this list. Returns empty list if no
2417 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002418 List is ordered sequentially
2419
andrewonlab3e15ead2014-10-15 14:21:34 -04002420 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002421 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002422 the ids. By obtaining the list of device ids on the fly,
2423 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002424 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002425 try:
kelvin8ec71442015-01-15 16:57:00 -08002426 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002427 devicesStr = self.devices( jsonFormat=False )
2428 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002429
kelvin-onlabd3b64892015-01-20 13:26:24 -08002430 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002431 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002432 return idList
kelvin8ec71442015-01-15 16:57:00 -08002433
2434 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002435 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002436 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002437 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002438 # Split list further into arguments before and after string
2439 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002440 # append to idList
2441 for arg in tempList:
2442 idList.append( arg.split( "id=" )[ 1 ] )
2443 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002444
Jon Halld4d4b372015-01-28 16:02:41 -08002445 except TypeError:
2446 main.log.exception( self.name + ": Object not as expected" )
2447 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002449 main.log.error( self.name + ": EOF exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002451 main.cleanup()
2452 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002454 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002455 main.cleanup()
2456 main.exit()
2457
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002459 """
andrewonlab7c211572014-10-15 16:45:20 -04002460 Uses 'nodes' function to obtain list of all nodes
2461 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002462 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002463 Returns:
2464 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002465 """
andrewonlab7c211572014-10-15 16:45:20 -04002466 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002467 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002468 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002469 # Sample nodesStr output
2470 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002472 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002473 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002474 nodesJson = json.loads( nodesStr )
2475 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002476 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002477 except ( TypeError, ValueError ):
2478 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002479 return None
andrewonlab7c211572014-10-15 16:45:20 -04002480 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002481 main.log.error( self.name + ": EOF exception found" )
2482 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002483 main.cleanup()
2484 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002485 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002486 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002487 main.cleanup()
2488 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002489
kelvin-onlabd3b64892015-01-20 13:26:24 -08002490 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002491 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002492 Return the first device from the devices api whose 'id' contains 'dpid'
2493 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002494 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002495 try:
kelvin8ec71442015-01-15 16:57:00 -08002496 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002497 return None
2498 else:
kelvin8ec71442015-01-15 16:57:00 -08002499 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002500 rawDevices = self.devices()
2501 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002502 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002503 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002504 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2505 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002506 return device
2507 return None
Jon Hallc6793552016-01-19 14:18:37 -08002508 except ( TypeError, ValueError ):
2509 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002510 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002511 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002512 main.log.error( self.name + ": EOF exception found" )
2513 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002514 main.cleanup()
2515 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002516 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002517 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002518 main.cleanup()
2519 main.exit()
2520
kelvin-onlabd3b64892015-01-20 13:26:24 -08002521 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002522 """
Jon Hallefbd9792015-03-05 16:11:36 -08002523 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002524 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002525 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002526
Jon Hall42db6dc2014-10-24 19:03:48 -04002527 Params: ip = ip used for the onos cli
2528 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002529 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 logLevel = level to log to. Currently accepts
2531 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002532
2533
kelvin-onlabd3b64892015-01-20 13:26:24 -08002534 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002535
Jon Hallefbd9792015-03-05 16:11:36 -08002536 Returns: main.TRUE if the number of switches and links are correct,
2537 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002538 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002539 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002540 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002542 if topology == {}:
2543 return main.ERROR
2544 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002545 # Is the number of switches is what we expected
2546 devices = topology.get( 'devices', False )
2547 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002548 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002549 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002550 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002551 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 linkCheck = ( int( links ) == int( numolink ) )
2553 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002554 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002555 output += "The number of links and switches match " +\
2556 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002557 result = main.TRUE
2558 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002559 output += "The number of links and switches does not match " +\
2560 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002561 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002562 output = output + "\n ONOS sees %i devices (%i expected) \
2563 and %i links (%i expected)" % (
2564 int( devices ), int( numoswitch ), int( links ),
2565 int( numolink ) )
2566 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002567 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002568 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002569 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002570 else:
Jon Hall390696c2015-05-05 17:13:41 -07002571 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002572 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002573 except TypeError:
2574 main.log.exception( self.name + ": Object not as expected" )
2575 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002576 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002577 main.log.error( self.name + ": EOF exception found" )
2578 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002579 main.cleanup()
2580 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002581 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002582 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002583 main.cleanup()
2584 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002585
kelvin-onlabd3b64892015-01-20 13:26:24 -08002586 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002587 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002588 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002589 deviceId must be the id of a device as seen in the onos devices command
2590 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002591 role must be either master, standby, or none
2592
Jon Halle3f39ff2015-01-13 11:50:53 -08002593 Returns:
2594 main.TRUE or main.FALSE based on argument verification and
2595 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002596 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002597 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002598 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002599 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002600 cmdStr = "device-role " +\
2601 str( deviceId ) + " " +\
2602 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002603 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002604 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002605 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002606 if re.search( "Error", handle ):
2607 # end color output to escape any colours
2608 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002610 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002611 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002612 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002613 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002614 main.log.error( "Invalid 'role' given to device_role(). " +
2615 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002616 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002617 except AssertionError:
2618 main.log.exception( "" )
2619 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002620 except TypeError:
2621 main.log.exception( self.name + ": Object not as expected" )
2622 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002623 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002624 main.log.error( self.name + ": EOF exception found" )
2625 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002626 main.cleanup()
2627 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002628 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002629 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002630 main.cleanup()
2631 main.exit()
2632
kelvin-onlabd3b64892015-01-20 13:26:24 -08002633 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002634 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002635 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002636 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002637 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002638 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002639 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002640 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002641 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002642 cmdStr += " -j"
2643 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002644 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002645 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002646 except AssertionError:
2647 main.log.exception( "" )
2648 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002649 except TypeError:
2650 main.log.exception( self.name + ": Object not as expected" )
2651 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002652 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002653 main.log.error( self.name + ": EOF exception found" )
2654 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002655 main.cleanup()
2656 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002658 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002659 main.cleanup()
2660 main.exit()
2661
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002663 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002664 CLI command to get the current leader for the Election test application
2665 NOTE: Requires installation of the onos-app-election feature
2666 Returns: Node IP of the leader if one exists
2667 None if none exists
2668 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002669 """
Jon Hall94fd0472014-12-08 11:52:42 -08002670 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002671 cmdStr = "election-test-leader"
2672 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002673 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002674 # Leader
2675 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002676 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 nodeSearch = re.search( leaderPattern, response )
2678 if nodeSearch:
2679 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002680 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002681 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002682 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002683 # no leader
2684 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002685 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 nullSearch = re.search( nullPattern, response )
2687 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002688 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002689 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002690 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002691 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002692 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002693 if re.search( errorPattern, response ):
2694 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002695 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002696 return main.FALSE
2697 else:
Jon Hall390696c2015-05-05 17:13:41 -07002698 main.log.error( "Error in electionTestLeader on " + self.name +
2699 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002700 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002701 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002702 except AssertionError:
2703 main.log.exception( "" )
2704 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002705 except TypeError:
2706 main.log.exception( self.name + ": Object not as expected" )
2707 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002708 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002709 main.log.error( self.name + ": EOF exception found" )
2710 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002711 main.cleanup()
2712 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002713 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002714 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002715 main.cleanup()
2716 main.exit()
2717
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002719 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002720 CLI command to run for leadership of the Election test application.
2721 NOTE: Requires installation of the onos-app-election feature
2722 Returns: Main.TRUE on success
2723 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002724 """
Jon Hall94fd0472014-12-08 11:52:42 -08002725 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002726 cmdStr = "election-test-run"
2727 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002728 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002729 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002730 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002731 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002732 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002733 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002734 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002735 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002736 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002737 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002738 errorPattern = "Command\snot\sfound"
2739 if re.search( errorPattern, response ):
2740 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002741 return main.FALSE
2742 else:
Jon Hall390696c2015-05-05 17:13:41 -07002743 main.log.error( "Error in electionTestRun on " + self.name +
2744 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002745 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002746 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002747 except AssertionError:
2748 main.log.exception( "" )
2749 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002750 except TypeError:
2751 main.log.exception( self.name + ": Object not as expected" )
2752 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002753 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002754 main.log.error( self.name + ": EOF exception found" )
2755 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002756 main.cleanup()
2757 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002758 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002759 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002760 main.cleanup()
2761 main.exit()
2762
kelvin-onlabd3b64892015-01-20 13:26:24 -08002763 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002764 """
Jon Hall94fd0472014-12-08 11:52:42 -08002765 * CLI command to withdraw the local node from leadership election for
2766 * the Election test application.
2767 #NOTE: Requires installation of the onos-app-election feature
2768 Returns: Main.TRUE on success
2769 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002770 """
Jon Hall94fd0472014-12-08 11:52:42 -08002771 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002772 cmdStr = "election-test-withdraw"
2773 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002774 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002775 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002776 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002777 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002778 if re.search( successPattern, response ):
2779 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002780 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002781 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002782 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002783 errorPattern = "Command\snot\sfound"
2784 if re.search( errorPattern, response ):
2785 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002786 return main.FALSE
2787 else:
Jon Hall390696c2015-05-05 17:13:41 -07002788 main.log.error( "Error in electionTestWithdraw on " +
2789 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002790 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002791 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002792 except AssertionError:
2793 main.log.exception( "" )
2794 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002795 except TypeError:
2796 main.log.exception( self.name + ": Object not as expected" )
2797 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002798 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002799 main.log.error( self.name + ": EOF exception found" )
2800 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002801 main.cleanup()
2802 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002804 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002805 main.cleanup()
2806 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002807
kelvin8ec71442015-01-15 16:57:00 -08002808 def getDevicePortsEnabledCount( self, dpid ):
2809 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002810 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002811 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002812 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002813 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2815 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002816 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002817 if re.search( "No such device", output ):
2818 main.log.error( "Error in getting ports" )
2819 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002820 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002821 return output
Jon Hallc6793552016-01-19 14:18:37 -08002822 except AssertionError:
2823 main.log.exception( "" )
2824 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002825 except TypeError:
2826 main.log.exception( self.name + ": Object not as expected" )
2827 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002828 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002829 main.log.error( self.name + ": EOF exception found" )
2830 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002831 main.cleanup()
2832 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002833 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002834 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002835 main.cleanup()
2836 main.exit()
2837
kelvin8ec71442015-01-15 16:57:00 -08002838 def getDeviceLinksActiveCount( self, dpid ):
2839 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002840 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002841 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002842 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002843 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002844 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2845 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002846 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002847 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002848 main.log.error( "Error in getting ports " )
2849 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002850 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002851 return output
Jon Hallc6793552016-01-19 14:18:37 -08002852 except AssertionError:
2853 main.log.exception( "" )
2854 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002855 except TypeError:
2856 main.log.exception( self.name + ": Object not as expected" )
2857 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002858 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002859 main.log.error( self.name + ": EOF exception found" )
2860 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002861 main.cleanup()
2862 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002863 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002864 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002865 main.cleanup()
2866 main.exit()
2867
kelvin8ec71442015-01-15 16:57:00 -08002868 def getAllIntentIds( self ):
2869 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002870 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002871 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002872 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002873 cmdStr = "onos:intents | grep id="
2874 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002875 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002876 if re.search( "Error", output ):
2877 main.log.error( "Error in getting ports" )
2878 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002879 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002880 return output
Jon Hallc6793552016-01-19 14:18:37 -08002881 except AssertionError:
2882 main.log.exception( "" )
2883 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002884 except TypeError:
2885 main.log.exception( self.name + ": Object not as expected" )
2886 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002888 main.log.error( self.name + ": EOF exception found" )
2889 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002890 main.cleanup()
2891 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002893 main.log.exception( self.name + ": Uncaught exception!" )
2894 main.cleanup()
2895 main.exit()
2896
Jon Hall73509952015-02-24 16:42:56 -08002897 def intentSummary( self ):
2898 """
Jon Hallefbd9792015-03-05 16:11:36 -08002899 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002900 """
2901 try:
2902 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002903 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002904 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002905 states.append( intent.get( 'state', None ) )
2906 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002907 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002908 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002909 except ( TypeError, ValueError ):
2910 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002911 return None
2912 except pexpect.EOF:
2913 main.log.error( self.name + ": EOF exception found" )
2914 main.log.error( self.name + ": " + self.handle.before )
2915 main.cleanup()
2916 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002917 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002918 main.log.exception( self.name + ": Uncaught exception!" )
2919 main.cleanup()
2920 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002921
Jon Hall61282e32015-03-19 11:34:11 -07002922 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002923 """
2924 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002925 Optional argument:
2926 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002927 """
Jon Hall63604932015-02-26 17:09:50 -08002928 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002929 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002930 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002931 cmdStr += " -j"
2932 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002933 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002934 return output
Jon Hallc6793552016-01-19 14:18:37 -08002935 except AssertionError:
2936 main.log.exception( "" )
2937 return None
Jon Hall63604932015-02-26 17:09:50 -08002938 except TypeError:
2939 main.log.exception( self.name + ": Object not as expected" )
2940 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002941 except pexpect.EOF:
2942 main.log.error( self.name + ": EOF exception found" )
2943 main.log.error( self.name + ": " + self.handle.before )
2944 main.cleanup()
2945 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002946 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002947 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002948 main.cleanup()
2949 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002950
acsmarsa4a4d1e2015-07-10 16:01:24 -07002951 def leaderCandidates( self, jsonFormat=True ):
2952 """
2953 Returns the output of the leaders -c command.
2954 Optional argument:
2955 * jsonFormat - boolean indicating if you want output in json
2956 """
2957 try:
2958 cmdStr = "onos:leaders -c"
2959 if jsonFormat:
2960 cmdStr += " -j"
2961 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002962 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002963 return output
Jon Hallc6793552016-01-19 14:18:37 -08002964 except AssertionError:
2965 main.log.exception( "" )
2966 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002967 except TypeError:
2968 main.log.exception( self.name + ": Object not as expected" )
2969 return None
2970 except pexpect.EOF:
2971 main.log.error( self.name + ": EOF exception found" )
2972 main.log.error( self.name + ": " + self.handle.before )
2973 main.cleanup()
2974 main.exit()
2975 except Exception:
2976 main.log.exception( self.name + ": Uncaught exception!" )
2977 main.cleanup()
2978 main.exit()
2979
Jon Hallc6793552016-01-19 14:18:37 -08002980 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002981 """
2982 Returns a list in format [leader,candidate1,candidate2,...] for a given
2983 topic parameter and an empty list if the topic doesn't exist
2984 If no leader is elected leader in the returned list will be "none"
2985 Returns None if there is a type error processing the json object
2986 """
2987 try:
2988 cmdStr = "onos:leaders -c -j"
Jon Hallc6793552016-01-19 14:18:37 -08002989 rawOutput = self.sendline( cmdStr )
2990 assert "Command not found:" not in rawOutput, rawOutput
2991 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002992 results = []
2993 for dict in output:
2994 if dict["topic"] == topic:
2995 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002996 candidates = re.split( ", ", dict["candidates"][1:-1] )
2997 results.append( leader )
2998 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002999 return results
Jon Hallc6793552016-01-19 14:18:37 -08003000 except AssertionError:
3001 main.log.exception( "" )
3002 return None
3003 except ( TypeError, ValueError ):
3004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003005 return None
3006 except pexpect.EOF:
3007 main.log.error( self.name + ": EOF exception found" )
3008 main.log.error( self.name + ": " + self.handle.before )
3009 main.cleanup()
3010 main.exit()
3011 except Exception:
3012 main.log.exception( self.name + ": Uncaught exception!" )
3013 main.cleanup()
3014 main.exit()
3015
Jon Hall61282e32015-03-19 11:34:11 -07003016 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003017 """
3018 Returns the output of the intent Pending map.
3019 """
Jon Hall63604932015-02-26 17:09:50 -08003020 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003021 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003022 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003023 cmdStr += " -j"
3024 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003025 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003026 return output
Jon Hallc6793552016-01-19 14:18:37 -08003027 except AssertionError:
3028 main.log.exception( "" )
3029 return None
Jon Hall63604932015-02-26 17:09:50 -08003030 except TypeError:
3031 main.log.exception( self.name + ": Object not as expected" )
3032 return None
3033 except pexpect.EOF:
3034 main.log.error( self.name + ": EOF exception found" )
3035 main.log.error( self.name + ": " + self.handle.before )
3036 main.cleanup()
3037 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003038 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003039 main.log.exception( self.name + ": Uncaught exception!" )
3040 main.cleanup()
3041 main.exit()
3042
Jon Hall61282e32015-03-19 11:34:11 -07003043 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003044 """
3045 Returns the output of the raft partitions command for ONOS.
3046 """
Jon Hall61282e32015-03-19 11:34:11 -07003047 # Sample JSON
3048 # {
3049 # "leader": "tcp://10.128.30.11:7238",
3050 # "members": [
3051 # "tcp://10.128.30.11:7238",
3052 # "tcp://10.128.30.17:7238",
3053 # "tcp://10.128.30.13:7238",
3054 # ],
3055 # "name": "p1",
3056 # "term": 3
3057 # },
Jon Hall63604932015-02-26 17:09:50 -08003058 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003059 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003060 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003061 cmdStr += " -j"
3062 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003063 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003064 return output
Jon Hallc6793552016-01-19 14:18:37 -08003065 except AssertionError:
3066 main.log.exception( "" )
3067 return None
Jon Hall63604932015-02-26 17:09:50 -08003068 except TypeError:
3069 main.log.exception( self.name + ": Object not as expected" )
3070 return None
3071 except pexpect.EOF:
3072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
3074 main.cleanup()
3075 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003076 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003077 main.log.exception( self.name + ": Uncaught exception!" )
3078 main.cleanup()
3079 main.exit()
3080
Jon Hallbe379602015-03-24 13:39:32 -07003081 def apps( self, jsonFormat=True ):
3082 """
3083 Returns the output of the apps command for ONOS. This command lists
3084 information about installed ONOS applications
3085 """
3086 # Sample JSON object
3087 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3088 # "description":"ONOS OpenFlow protocol southbound providers",
3089 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3090 # "features":"[onos-openflow]","state":"ACTIVE"}]
3091 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003092 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003093 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003094 cmdStr += " -j"
3095 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003096 assert "Command not found:" not in output, output
3097 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003098 return output
Jon Hallbe379602015-03-24 13:39:32 -07003099 # FIXME: look at specific exceptions/Errors
3100 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003101 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003102 return None
3103 except TypeError:
3104 main.log.exception( self.name + ": Object not as expected" )
3105 return None
3106 except pexpect.EOF:
3107 main.log.error( self.name + ": EOF exception found" )
3108 main.log.error( self.name + ": " + self.handle.before )
3109 main.cleanup()
3110 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003111 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003112 main.log.exception( self.name + ": Uncaught exception!" )
3113 main.cleanup()
3114 main.exit()
3115
Jon Hall146f1522015-03-24 15:33:24 -07003116 def appStatus( self, appName ):
3117 """
3118 Uses the onos:apps cli command to return the status of an application.
3119 Returns:
3120 "ACTIVE" - If app is installed and activated
3121 "INSTALLED" - If app is installed and deactivated
3122 "UNINSTALLED" - If app is not installed
3123 None - on error
3124 """
Jon Hall146f1522015-03-24 15:33:24 -07003125 try:
3126 if not isinstance( appName, types.StringType ):
3127 main.log.error( self.name + ".appStatus(): appName must be" +
3128 " a string" )
3129 return None
3130 output = self.apps( jsonFormat=True )
3131 appsJson = json.loads( output )
3132 state = None
3133 for app in appsJson:
3134 if appName == app.get('name'):
3135 state = app.get('state')
3136 break
3137 if state == "ACTIVE" or state == "INSTALLED":
3138 return state
3139 elif state is None:
3140 return "UNINSTALLED"
3141 elif state:
3142 main.log.error( "Unexpected state from 'onos:apps': " +
3143 str( state ) )
3144 return state
Jon Hallc6793552016-01-19 14:18:37 -08003145 except ( TypeError, ValueError ):
3146 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3147 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003148 return None
3149 except pexpect.EOF:
3150 main.log.error( self.name + ": EOF exception found" )
3151 main.log.error( self.name + ": " + self.handle.before )
3152 main.cleanup()
3153 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003154 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003155 main.log.exception( self.name + ": Uncaught exception!" )
3156 main.cleanup()
3157 main.exit()
3158
Jon Hallbe379602015-03-24 13:39:32 -07003159 def app( self, appName, option ):
3160 """
3161 Interacts with the app command for ONOS. This command manages
3162 application inventory.
3163 """
Jon Hallbe379602015-03-24 13:39:32 -07003164 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003165 # Validate argument types
3166 valid = True
3167 if not isinstance( appName, types.StringType ):
3168 main.log.error( self.name + ".app(): appName must be a " +
3169 "string" )
3170 valid = False
3171 if not isinstance( option, types.StringType ):
3172 main.log.error( self.name + ".app(): option must be a string" )
3173 valid = False
3174 if not valid:
3175 return main.FALSE
3176 # Validate Option
3177 option = option.lower()
3178 # NOTE: Install may become a valid option
3179 if option == "activate":
3180 pass
3181 elif option == "deactivate":
3182 pass
3183 elif option == "uninstall":
3184 pass
3185 else:
3186 # Invalid option
3187 main.log.error( "The ONOS app command argument only takes " +
3188 "the values: (activate|deactivate|uninstall)" +
3189 "; was given '" + option + "'")
3190 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003191 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003192 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003193 if "Error executing command" in output:
3194 main.log.error( "Error in processing onos:app command: " +
3195 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003196 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003197 elif "No such application" in output:
3198 main.log.error( "The application '" + appName +
3199 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003200 return main.FALSE
3201 elif "Command not found:" in output:
3202 main.log.error( "Error in processing onos:app command: " +
3203 str( output ) )
3204 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003205 elif "Unsupported command:" in output:
3206 main.log.error( "Incorrect command given to 'app': " +
3207 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003208 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003209 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003210 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003211 return main.TRUE
3212 except TypeError:
3213 main.log.exception( self.name + ": Object not as expected" )
3214 return main.ERROR
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
3218 main.cleanup()
3219 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003220 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003221 main.log.exception( self.name + ": Uncaught exception!" )
3222 main.cleanup()
3223 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003224
Jon Hallbd16b922015-03-26 17:53:15 -07003225 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003226 """
3227 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003228 appName is the hierarchical app name, not the feature name
3229 If check is True, method will check the status of the app after the
3230 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003231 Returns main.TRUE if the command was successfully sent
3232 main.FALSE if the cli responded with an error or given
3233 incorrect input
3234 """
3235 try:
3236 if not isinstance( appName, types.StringType ):
3237 main.log.error( self.name + ".activateApp(): appName must be" +
3238 " a string" )
3239 return main.FALSE
3240 status = self.appStatus( appName )
3241 if status == "INSTALLED":
3242 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003243 if check and response == main.TRUE:
3244 for i in range(10): # try 10 times then give up
3245 # TODO: Check with Thomas about this delay
3246 status = self.appStatus( appName )
3247 if status == "ACTIVE":
3248 return main.TRUE
3249 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003250 main.log.debug( "The state of application " +
3251 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003252 time.sleep( 1 )
3253 return main.FALSE
3254 else: # not 'check' or command didn't succeed
3255 return response
Jon Hall146f1522015-03-24 15:33:24 -07003256 elif status == "ACTIVE":
3257 return main.TRUE
3258 elif status == "UNINSTALLED":
3259 main.log.error( self.name + ": Tried to activate the " +
3260 "application '" + appName + "' which is not " +
3261 "installed." )
3262 else:
3263 main.log.error( "Unexpected return value from appStatus: " +
3264 str( status ) )
3265 return main.ERROR
3266 except TypeError:
3267 main.log.exception( self.name + ": Object not as expected" )
3268 return main.ERROR
3269 except pexpect.EOF:
3270 main.log.error( self.name + ": EOF exception found" )
3271 main.log.error( self.name + ": " + self.handle.before )
3272 main.cleanup()
3273 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003274 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003275 main.log.exception( self.name + ": Uncaught exception!" )
3276 main.cleanup()
3277 main.exit()
3278
Jon Hallbd16b922015-03-26 17:53:15 -07003279 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003280 """
3281 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003282 appName is the hierarchical app name, not the feature name
3283 If check is True, method will check the status of the app after the
3284 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003285 Returns main.TRUE if the command was successfully sent
3286 main.FALSE if the cli responded with an error or given
3287 incorrect input
3288 """
3289 try:
3290 if not isinstance( appName, types.StringType ):
3291 main.log.error( self.name + ".deactivateApp(): appName must " +
3292 "be a string" )
3293 return main.FALSE
3294 status = self.appStatus( appName )
3295 if status == "INSTALLED":
3296 return main.TRUE
3297 elif status == "ACTIVE":
3298 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003299 if check and response == main.TRUE:
3300 for i in range(10): # try 10 times then give up
3301 status = self.appStatus( appName )
3302 if status == "INSTALLED":
3303 return main.TRUE
3304 else:
3305 time.sleep( 1 )
3306 return main.FALSE
3307 else: # not check or command didn't succeed
3308 return response
Jon Hall146f1522015-03-24 15:33:24 -07003309 elif status == "UNINSTALLED":
3310 main.log.warn( self.name + ": Tried to deactivate the " +
3311 "application '" + appName + "' which is not " +
3312 "installed." )
3313 return main.TRUE
3314 else:
3315 main.log.error( "Unexpected return value from appStatus: " +
3316 str( status ) )
3317 return main.ERROR
3318 except TypeError:
3319 main.log.exception( self.name + ": Object not as expected" )
3320 return main.ERROR
3321 except pexpect.EOF:
3322 main.log.error( self.name + ": EOF exception found" )
3323 main.log.error( self.name + ": " + self.handle.before )
3324 main.cleanup()
3325 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003326 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003327 main.log.exception( self.name + ": Uncaught exception!" )
3328 main.cleanup()
3329 main.exit()
3330
Jon Hallbd16b922015-03-26 17:53:15 -07003331 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003332 """
3333 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003334 appName is the hierarchical app name, not the feature name
3335 If check is True, method will check the status of the app after the
3336 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003337 Returns main.TRUE if the command was successfully sent
3338 main.FALSE if the cli responded with an error or given
3339 incorrect input
3340 """
3341 # TODO: check with Thomas about the state machine for apps
3342 try:
3343 if not isinstance( appName, types.StringType ):
3344 main.log.error( self.name + ".uninstallApp(): appName must " +
3345 "be a string" )
3346 return main.FALSE
3347 status = self.appStatus( appName )
3348 if status == "INSTALLED":
3349 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003350 if check and response == main.TRUE:
3351 for i in range(10): # try 10 times then give up
3352 status = self.appStatus( appName )
3353 if status == "UNINSTALLED":
3354 return main.TRUE
3355 else:
3356 time.sleep( 1 )
3357 return main.FALSE
3358 else: # not check or command didn't succeed
3359 return response
Jon Hall146f1522015-03-24 15:33:24 -07003360 elif status == "ACTIVE":
3361 main.log.warn( self.name + ": Tried to uninstall the " +
3362 "application '" + appName + "' which is " +
3363 "currently active." )
3364 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003365 if check and response == main.TRUE:
3366 for i in range(10): # try 10 times then give up
3367 status = self.appStatus( appName )
3368 if status == "UNINSTALLED":
3369 return main.TRUE
3370 else:
3371 time.sleep( 1 )
3372 return main.FALSE
3373 else: # not check or command didn't succeed
3374 return response
Jon Hall146f1522015-03-24 15:33:24 -07003375 elif status == "UNINSTALLED":
3376 return main.TRUE
3377 else:
3378 main.log.error( "Unexpected return value from appStatus: " +
3379 str( status ) )
3380 return main.ERROR
3381 except TypeError:
3382 main.log.exception( self.name + ": Object not as expected" )
3383 return main.ERROR
3384 except pexpect.EOF:
3385 main.log.error( self.name + ": EOF exception found" )
3386 main.log.error( self.name + ": " + self.handle.before )
3387 main.cleanup()
3388 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003389 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003390 main.log.exception( self.name + ": Uncaught exception!" )
3391 main.cleanup()
3392 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003393
3394 def appIDs( self, jsonFormat=True ):
3395 """
3396 Show the mappings between app id and app names given by the 'app-ids'
3397 cli command
3398 """
3399 try:
3400 cmdStr = "app-ids"
3401 if jsonFormat:
3402 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003403 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003404 assert "Command not found:" not in output, output
3405 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003406 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003407 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003408 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003409 return None
3410 except TypeError:
3411 main.log.exception( self.name + ": Object not as expected" )
3412 return None
3413 except pexpect.EOF:
3414 main.log.error( self.name + ": EOF exception found" )
3415 main.log.error( self.name + ": " + self.handle.before )
3416 main.cleanup()
3417 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003418 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003419 main.log.exception( self.name + ": Uncaught exception!" )
3420 main.cleanup()
3421 main.exit()
3422
3423 def appToIDCheck( self ):
3424 """
3425 This method will check that each application's ID listed in 'apps' is
3426 the same as the ID listed in 'app-ids'. The check will also check that
3427 there are no duplicate IDs issued. Note that an app ID should be
3428 a globaly unique numerical identifier for app/app-like features. Once
3429 an ID is registered, the ID is never freed up so that if an app is
3430 reinstalled it will have the same ID.
3431
3432 Returns: main.TRUE if the check passes and
3433 main.FALSE if the check fails or
3434 main.ERROR if there is some error in processing the test
3435 """
3436 try:
Jon Hall390696c2015-05-05 17:13:41 -07003437 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003438 rawJson = self.appIDs( jsonFormat=True )
3439 if rawJson:
3440 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003441 else:
Jon Hallc6793552016-01-19 14:18:37 -08003442 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003443 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003444 rawJson = self.apps( jsonFormat=True )
3445 if rawJson:
3446 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003447 else:
Jon Hallc6793552016-01-19 14:18:37 -08003448 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003449 bail = True
3450 if bail:
3451 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003452 result = main.TRUE
3453 for app in apps:
3454 appID = app.get( 'id' )
3455 if appID is None:
3456 main.log.error( "Error parsing app: " + str( app ) )
3457 result = main.FALSE
3458 appName = app.get( 'name' )
3459 if appName is None:
3460 main.log.error( "Error parsing app: " + str( app ) )
3461 result = main.FALSE
3462 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003463 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003464 # main.log.debug( "Comparing " + str( app ) + " to " +
3465 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003466 if not current: # if ids doesn't have this id
3467 result = main.FALSE
3468 main.log.error( "'app-ids' does not have the ID for " +
3469 str( appName ) + " that apps does." )
3470 elif len( current ) > 1:
3471 # there is more than one app with this ID
3472 result = main.FALSE
3473 # We will log this later in the method
3474 elif not current[0][ 'name' ] == appName:
3475 currentName = current[0][ 'name' ]
3476 result = main.FALSE
3477 main.log.error( "'app-ids' has " + str( currentName ) +
3478 " registered under id:" + str( appID ) +
3479 " but 'apps' has " + str( appName ) )
3480 else:
3481 pass # id and name match!
3482 # now make sure that app-ids has no duplicates
3483 idsList = []
3484 namesList = []
3485 for item in ids:
3486 idsList.append( item[ 'id' ] )
3487 namesList.append( item[ 'name' ] )
3488 if len( idsList ) != len( set( idsList ) ) or\
3489 len( namesList ) != len( set( namesList ) ):
3490 main.log.error( "'app-ids' has some duplicate entries: \n"
3491 + json.dumps( ids,
3492 sort_keys=True,
3493 indent=4,
3494 separators=( ',', ': ' ) ) )
3495 result = main.FALSE
3496 return result
Jon Hallc6793552016-01-19 14:18:37 -08003497 except ( TypeError, ValueError ):
3498 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003499 return main.ERROR
3500 except pexpect.EOF:
3501 main.log.error( self.name + ": EOF exception found" )
3502 main.log.error( self.name + ": " + self.handle.before )
3503 main.cleanup()
3504 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003505 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003506 main.log.exception( self.name + ": Uncaught exception!" )
3507 main.cleanup()
3508 main.exit()
3509
Jon Hallfb760a02015-04-13 15:35:03 -07003510 def getCfg( self, component=None, propName=None, short=False,
3511 jsonFormat=True ):
3512 """
3513 Get configuration settings from onos cli
3514 Optional arguments:
3515 component - Optionally only list configurations for a specific
3516 component. If None, all components with configurations
3517 are displayed. Case Sensitive string.
3518 propName - If component is specified, propName option will show
3519 only this specific configuration from that component.
3520 Case Sensitive string.
3521 jsonFormat - Returns output as json. Note that this will override
3522 the short option
3523 short - Short, less verbose, version of configurations.
3524 This is overridden by the json option
3525 returns:
3526 Output from cli as a string or None on error
3527 """
3528 try:
3529 baseStr = "cfg"
3530 cmdStr = " get"
3531 componentStr = ""
3532 if component:
3533 componentStr += " " + component
3534 if propName:
3535 componentStr += " " + propName
3536 if jsonFormat:
3537 baseStr += " -j"
3538 elif short:
3539 baseStr += " -s"
3540 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003541 assert "Command not found:" not in output, output
3542 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003543 return output
3544 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003545 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003546 return None
3547 except TypeError:
3548 main.log.exception( self.name + ": Object not as expected" )
3549 return None
3550 except pexpect.EOF:
3551 main.log.error( self.name + ": EOF exception found" )
3552 main.log.error( self.name + ": " + self.handle.before )
3553 main.cleanup()
3554 main.exit()
3555 except Exception:
3556 main.log.exception( self.name + ": Uncaught exception!" )
3557 main.cleanup()
3558 main.exit()
3559
3560 def setCfg( self, component, propName, value=None, check=True ):
3561 """
3562 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003563 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003564 component - The case sensitive name of the component whose
3565 property is to be set
3566 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003567 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003568 value - The value to set the property to. If None, will unset the
3569 property and revert it to it's default value(if applicable)
3570 check - Boolean, Check whether the option was successfully set this
3571 only applies when a value is given.
3572 returns:
3573 main.TRUE on success or main.FALSE on failure. If check is False,
3574 will return main.TRUE unless there is an error
3575 """
3576 try:
3577 baseStr = "cfg"
3578 cmdStr = " set " + str( component ) + " " + str( propName )
3579 if value is not None:
3580 cmdStr += " " + str( value )
3581 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003582 assert "Command not found:" not in output, output
3583 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003584 if value and check:
3585 results = self.getCfg( component=str( component ),
3586 propName=str( propName ),
3587 jsonFormat=True )
3588 # Check if current value is what we just set
3589 try:
3590 jsonOutput = json.loads( results )
3591 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003592 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003593 main.log.exception( "Error parsing cfg output" )
3594 main.log.error( "output:" + repr( results ) )
3595 return main.FALSE
3596 if current == str( value ):
3597 return main.TRUE
3598 return main.FALSE
3599 return main.TRUE
3600 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003601 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003602 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003603 except ( TypeError, ValueError ):
3604 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003605 return main.FALSE
3606 except pexpect.EOF:
3607 main.log.error( self.name + ": EOF exception found" )
3608 main.log.error( self.name + ": " + self.handle.before )
3609 main.cleanup()
3610 main.exit()
3611 except Exception:
3612 main.log.exception( self.name + ": Uncaught exception!" )
3613 main.cleanup()
3614 main.exit()
3615
Jon Hall390696c2015-05-05 17:13:41 -07003616 def setTestAdd( self, setName, values ):
3617 """
3618 CLI command to add elements to a distributed set.
3619 Arguments:
3620 setName - The name of the set to add to.
3621 values - The value(s) to add to the set, space seperated.
3622 Example usages:
3623 setTestAdd( "set1", "a b c" )
3624 setTestAdd( "set2", "1" )
3625 returns:
3626 main.TRUE on success OR
3627 main.FALSE if elements were already in the set OR
3628 main.ERROR on error
3629 """
3630 try:
3631 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3632 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003633 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003634 try:
3635 # TODO: Maybe make this less hardcoded
3636 # ConsistentMap Exceptions
3637 assert "org.onosproject.store.service" not in output
3638 # Node not leader
3639 assert "java.lang.IllegalStateException" not in output
3640 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003641 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003642 "command: " + str( output ) )
3643 retryTime = 30 # Conservative time, given by Madan
3644 main.log.info( "Waiting " + str( retryTime ) +
3645 "seconds before retrying." )
3646 time.sleep( retryTime ) # Due to change in mastership
3647 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003648 assert "Error executing command" not in output
3649 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3650 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3651 main.log.info( self.name + ": " + output )
3652 if re.search( positiveMatch, output):
3653 return main.TRUE
3654 elif re.search( negativeMatch, output):
3655 return main.FALSE
3656 else:
3657 main.log.error( self.name + ": setTestAdd did not" +
3658 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003659 main.log.debug( self.name + " actual: " + repr( output ) )
3660 return main.ERROR
3661 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003662 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003663 return main.ERROR
3664 except TypeError:
3665 main.log.exception( self.name + ": Object not as expected" )
3666 return main.ERROR
3667 except pexpect.EOF:
3668 main.log.error( self.name + ": EOF exception found" )
3669 main.log.error( self.name + ": " + self.handle.before )
3670 main.cleanup()
3671 main.exit()
3672 except Exception:
3673 main.log.exception( self.name + ": Uncaught exception!" )
3674 main.cleanup()
3675 main.exit()
3676
3677 def setTestRemove( self, setName, values, clear=False, retain=False ):
3678 """
3679 CLI command to remove elements from a distributed set.
3680 Required arguments:
3681 setName - The name of the set to remove from.
3682 values - The value(s) to remove from the set, space seperated.
3683 Optional arguments:
3684 clear - Clear all elements from the set
3685 retain - Retain only the given values. (intersection of the
3686 original set and the given set)
3687 returns:
3688 main.TRUE on success OR
3689 main.FALSE if the set was not changed OR
3690 main.ERROR on error
3691 """
3692 try:
3693 cmdStr = "set-test-remove "
3694 if clear:
3695 cmdStr += "-c " + str( setName )
3696 elif retain:
3697 cmdStr += "-r " + str( setName ) + " " + str( values )
3698 else:
3699 cmdStr += str( setName ) + " " + str( values )
3700 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003701 try:
3702 # TODO: Maybe make this less hardcoded
3703 # ConsistentMap Exceptions
3704 assert "org.onosproject.store.service" not in output
3705 # Node not leader
3706 assert "java.lang.IllegalStateException" not in output
3707 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003708 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003709 "command: " + str( output ) )
3710 retryTime = 30 # Conservative time, given by Madan
3711 main.log.info( "Waiting " + str( retryTime ) +
3712 "seconds before retrying." )
3713 time.sleep( retryTime ) # Due to change in mastership
3714 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
3716 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003717 main.log.info( self.name + ": " + output )
3718 if clear:
3719 pattern = "Set " + str( setName ) + " cleared"
3720 if re.search( pattern, output ):
3721 return main.TRUE
3722 elif retain:
3723 positivePattern = str( setName ) + " was pruned to contain " +\
3724 "only elements of set \[(.*)\]"
3725 negativePattern = str( setName ) + " was not changed by " +\
3726 "retaining only elements of the set " +\
3727 "\[(.*)\]"
3728 if re.search( positivePattern, output ):
3729 return main.TRUE
3730 elif re.search( negativePattern, output ):
3731 return main.FALSE
3732 else:
3733 positivePattern = "\[(.*)\] was removed from the set " +\
3734 str( setName )
3735 if ( len( values.split() ) == 1 ):
3736 negativePattern = "\[(.*)\] was not in set " +\
3737 str( setName )
3738 else:
3739 negativePattern = "No element of \[(.*)\] was in set " +\
3740 str( setName )
3741 if re.search( positivePattern, output ):
3742 return main.TRUE
3743 elif re.search( negativePattern, output ):
3744 return main.FALSE
3745 main.log.error( self.name + ": setTestRemove did not" +
3746 " match expected output" )
3747 main.log.debug( self.name + " expected: " + pattern )
3748 main.log.debug( self.name + " actual: " + repr( output ) )
3749 return main.ERROR
3750 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003751 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003752 return main.ERROR
3753 except TypeError:
3754 main.log.exception( self.name + ": Object not as expected" )
3755 return main.ERROR
3756 except pexpect.EOF:
3757 main.log.error( self.name + ": EOF exception found" )
3758 main.log.error( self.name + ": " + self.handle.before )
3759 main.cleanup()
3760 main.exit()
3761 except Exception:
3762 main.log.exception( self.name + ": Uncaught exception!" )
3763 main.cleanup()
3764 main.exit()
3765
3766 def setTestGet( self, setName, values="" ):
3767 """
3768 CLI command to get the elements in a distributed set.
3769 Required arguments:
3770 setName - The name of the set to remove from.
3771 Optional arguments:
3772 values - The value(s) to check if in the set, space seperated.
3773 returns:
3774 main.ERROR on error OR
3775 A list of elements in the set if no optional arguments are
3776 supplied OR
3777 A tuple containing the list then:
3778 main.FALSE if the given values are not in the set OR
3779 main.TRUE if the given values are in the set OR
3780 """
3781 try:
3782 values = str( values ).strip()
3783 setName = str( setName ).strip()
3784 length = len( values.split() )
3785 containsCheck = None
3786 # Patterns to match
3787 setPattern = "\[(.*)\]"
3788 pattern = "Items in set " + setName + ":\n" + setPattern
3789 containsTrue = "Set " + setName + " contains the value " + values
3790 containsFalse = "Set " + setName + " did not contain the value " +\
3791 values
3792 containsAllTrue = "Set " + setName + " contains the the subset " +\
3793 setPattern
3794 containsAllFalse = "Set " + setName + " did not contain the the" +\
3795 " subset " + setPattern
3796
3797 cmdStr = "set-test-get "
3798 cmdStr += setName + " " + values
3799 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003800 try:
3801 # TODO: Maybe make this less hardcoded
3802 # ConsistentMap Exceptions
3803 assert "org.onosproject.store.service" not in output
3804 # Node not leader
3805 assert "java.lang.IllegalStateException" not in output
3806 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003807 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003808 "command: " + str( output ) )
3809 retryTime = 30 # Conservative time, given by Madan
3810 main.log.info( "Waiting " + str( retryTime ) +
3811 "seconds before retrying." )
3812 time.sleep( retryTime ) # Due to change in mastership
3813 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003814 assert "Command not found:" not in output, output
3815 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003816 main.log.info( self.name + ": " + output )
3817
3818 if length == 0:
3819 match = re.search( pattern, output )
3820 else: # if given values
3821 if length == 1: # Contains output
3822 patternTrue = pattern + "\n" + containsTrue
3823 patternFalse = pattern + "\n" + containsFalse
3824 else: # ContainsAll output
3825 patternTrue = pattern + "\n" + containsAllTrue
3826 patternFalse = pattern + "\n" + containsAllFalse
3827 matchTrue = re.search( patternTrue, output )
3828 matchFalse = re.search( patternFalse, output )
3829 if matchTrue:
3830 containsCheck = main.TRUE
3831 match = matchTrue
3832 elif matchFalse:
3833 containsCheck = main.FALSE
3834 match = matchFalse
3835 else:
3836 main.log.error( self.name + " setTestGet did not match " +\
3837 "expected output" )
3838 main.log.debug( self.name + " expected: " + pattern )
3839 main.log.debug( self.name + " actual: " + repr( output ) )
3840 match = None
3841 if match:
3842 setMatch = match.group( 1 )
3843 if setMatch == '':
3844 setList = []
3845 else:
3846 setList = setMatch.split( ", " )
3847 if length > 0:
3848 return ( setList, containsCheck )
3849 else:
3850 return setList
3851 else: # no match
3852 main.log.error( self.name + ": setTestGet did not" +
3853 " match expected output" )
3854 main.log.debug( self.name + " expected: " + pattern )
3855 main.log.debug( self.name + " actual: " + repr( output ) )
3856 return main.ERROR
3857 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003858 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003859 return main.ERROR
3860 except TypeError:
3861 main.log.exception( self.name + ": Object not as expected" )
3862 return main.ERROR
3863 except pexpect.EOF:
3864 main.log.error( self.name + ": EOF exception found" )
3865 main.log.error( self.name + ": " + self.handle.before )
3866 main.cleanup()
3867 main.exit()
3868 except Exception:
3869 main.log.exception( self.name + ": Uncaught exception!" )
3870 main.cleanup()
3871 main.exit()
3872
3873 def setTestSize( self, setName ):
3874 """
3875 CLI command to get the elements in a distributed set.
3876 Required arguments:
3877 setName - The name of the set to remove from.
3878 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003879 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003880 None on error
3881 """
3882 try:
3883 # TODO: Should this check against the number of elements returned
3884 # and then return true/false based on that?
3885 setName = str( setName ).strip()
3886 # Patterns to match
3887 setPattern = "\[(.*)\]"
3888 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3889 setPattern
3890 cmdStr = "set-test-get -s "
3891 cmdStr += setName
3892 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003893 try:
3894 # TODO: Maybe make this less hardcoded
3895 # ConsistentMap Exceptions
3896 assert "org.onosproject.store.service" not in output
3897 # Node not leader
3898 assert "java.lang.IllegalStateException" not in output
3899 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003900 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003901 "command: " + str( output ) )
3902 retryTime = 30 # Conservative time, given by Madan
3903 main.log.info( "Waiting " + str( retryTime ) +
3904 "seconds before retrying." )
3905 time.sleep( retryTime ) # Due to change in mastership
3906 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003907 assert "Command not found:" not in output, output
3908 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003909 main.log.info( self.name + ": " + output )
3910 match = re.search( pattern, output )
3911 if match:
3912 setSize = int( match.group( 1 ) )
3913 setMatch = match.group( 2 )
3914 if len( setMatch.split() ) == setSize:
3915 main.log.info( "The size returned by " + self.name +
3916 " matches the number of elements in " +
3917 "the returned set" )
3918 else:
3919 main.log.error( "The size returned by " + self.name +
3920 " does not match the number of " +
3921 "elements in the returned set." )
3922 return setSize
3923 else: # no match
3924 main.log.error( self.name + ": setTestGet did not" +
3925 " match expected output" )
3926 main.log.debug( self.name + " expected: " + pattern )
3927 main.log.debug( self.name + " actual: " + repr( output ) )
3928 return None
3929 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003930 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003931 return None
Jon Hall390696c2015-05-05 17:13:41 -07003932 except TypeError:
3933 main.log.exception( self.name + ": Object not as expected" )
3934 return None
3935 except pexpect.EOF:
3936 main.log.error( self.name + ": EOF exception found" )
3937 main.log.error( self.name + ": " + self.handle.before )
3938 main.cleanup()
3939 main.exit()
3940 except Exception:
3941 main.log.exception( self.name + ": Uncaught exception!" )
3942 main.cleanup()
3943 main.exit()
3944
Jon Hall80daded2015-05-27 16:07:00 -07003945 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003946 """
3947 Command to list the various counters in the system.
3948 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003949 if jsonFormat, a string of the json object returned by the cli
3950 command
3951 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003952 None on error
3953 """
Jon Hall390696c2015-05-05 17:13:41 -07003954 try:
3955 counters = {}
3956 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003957 if jsonFormat:
3958 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003959 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003960 assert "Command not found:" not in output, output
3961 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003962 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003963 return output
Jon Hall390696c2015-05-05 17:13:41 -07003964 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003965 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003966 return None
Jon Hall390696c2015-05-05 17:13:41 -07003967 except TypeError:
3968 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003969 return None
Jon Hall390696c2015-05-05 17:13:41 -07003970 except pexpect.EOF:
3971 main.log.error( self.name + ": EOF exception found" )
3972 main.log.error( self.name + ": " + self.handle.before )
3973 main.cleanup()
3974 main.exit()
3975 except Exception:
3976 main.log.exception( self.name + ": Uncaught exception!" )
3977 main.cleanup()
3978 main.exit()
3979
Jon Halle1a3b752015-07-22 13:02:46 -07003980 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003981 """
Jon Halle1a3b752015-07-22 13:02:46 -07003982 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003983 Required arguments:
3984 counter - The name of the counter to increment.
3985 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003986 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003987 inMemory - use in memory map for the counter
3988 returns:
3989 integer value of the counter or
3990 None on Error
3991 """
3992 try:
3993 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003994 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003995 cmdStr = "counter-test-increment "
3996 if inMemory:
3997 cmdStr += "-i "
3998 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003999 if delta != 1:
4000 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004001 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004002 try:
4003 # TODO: Maybe make this less hardcoded
4004 # ConsistentMap Exceptions
4005 assert "org.onosproject.store.service" not in output
4006 # Node not leader
4007 assert "java.lang.IllegalStateException" not in output
4008 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004009 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004010 "command: " + str( output ) )
4011 retryTime = 30 # Conservative time, given by Madan
4012 main.log.info( "Waiting " + str( retryTime ) +
4013 "seconds before retrying." )
4014 time.sleep( retryTime ) # Due to change in mastership
4015 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004016 assert "Command not found:" not in output, output
4017 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004018 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004019 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004020 match = re.search( pattern, output )
4021 if match:
4022 return int( match.group( 1 ) )
4023 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004024 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004025 " match expected output." )
4026 main.log.debug( self.name + " expected: " + pattern )
4027 main.log.debug( self.name + " actual: " + repr( output ) )
4028 return None
4029 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004030 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004031 return None
4032 except TypeError:
4033 main.log.exception( self.name + ": Object not as expected" )
4034 return None
4035 except pexpect.EOF:
4036 main.log.error( self.name + ": EOF exception found" )
4037 main.log.error( self.name + ": " + self.handle.before )
4038 main.cleanup()
4039 main.exit()
4040 except Exception:
4041 main.log.exception( self.name + ": Uncaught exception!" )
4042 main.cleanup()
4043 main.exit()
4044
Jon Halle1a3b752015-07-22 13:02:46 -07004045 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4046 """
4047 CLI command to get a distributed counter then add a delta to it.
4048 Required arguments:
4049 counter - The name of the counter to increment.
4050 Optional arguments:
4051 delta - The long to add to the counter
4052 inMemory - use in memory map for the counter
4053 returns:
4054 integer value of the counter or
4055 None on Error
4056 """
4057 try:
4058 counter = str( counter )
4059 delta = int( delta )
4060 cmdStr = "counter-test-increment -g "
4061 if inMemory:
4062 cmdStr += "-i "
4063 cmdStr += counter
4064 if delta != 1:
4065 cmdStr += " " + str( delta )
4066 output = self.sendline( cmdStr )
4067 try:
4068 # TODO: Maybe make this less hardcoded
4069 # ConsistentMap Exceptions
4070 assert "org.onosproject.store.service" not in output
4071 # Node not leader
4072 assert "java.lang.IllegalStateException" not in output
4073 except AssertionError:
4074 main.log.error( "Error in processing '" + cmdStr + "' " +
4075 "command: " + str( output ) )
4076 retryTime = 30 # Conservative time, given by Madan
4077 main.log.info( "Waiting " + str( retryTime ) +
4078 "seconds before retrying." )
4079 time.sleep( retryTime ) # Due to change in mastership
4080 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004081 assert "Command not found:" not in output, output
4082 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004083 main.log.info( self.name + ": " + output )
4084 pattern = counter + " was updated to (-?\d+)"
4085 match = re.search( pattern, output )
4086 if match:
4087 return int( match.group( 1 ) )
4088 else:
4089 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4090 " match expected output." )
4091 main.log.debug( self.name + " expected: " + pattern )
4092 main.log.debug( self.name + " actual: " + repr( output ) )
4093 return None
4094 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004095 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004096 return None
4097 except TypeError:
4098 main.log.exception( self.name + ": Object not as expected" )
4099 return None
4100 except pexpect.EOF:
4101 main.log.error( self.name + ": EOF exception found" )
4102 main.log.error( self.name + ": " + self.handle.before )
4103 main.cleanup()
4104 main.exit()
4105 except Exception:
4106 main.log.exception( self.name + ": Uncaught exception!" )
4107 main.cleanup()
4108 main.exit()
4109
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004110 def summary( self, jsonFormat=True ):
4111 """
4112 Description: Execute summary command in onos
4113 Returns: json object ( summary -j ), returns main.FALSE if there is
4114 no output
4115
4116 """
4117 try:
4118 cmdStr = "summary"
4119 if jsonFormat:
4120 cmdStr += " -j"
4121 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004122 assert "Command not found:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004123 if re.search( "Error:", handle ):
4124 main.log.error( self.name + ": summary() response: " +
4125 str( handle ) )
4126 if not handle:
4127 main.log.error( self.name + ": There is no output in " +
4128 "summary command" )
4129 return main.FALSE
4130 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004131 except AssertionError:
4132 main.log.exception( "" )
4133 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004134 except TypeError:
4135 main.log.exception( self.name + ": Object not as expected" )
4136 return None
4137 except pexpect.EOF:
4138 main.log.error( self.name + ": EOF exception found" )
4139 main.log.error( self.name + ": " + self.handle.before )
4140 main.cleanup()
4141 main.exit()
4142 except Exception:
4143 main.log.exception( self.name + ": Uncaught exception!" )
4144 main.cleanup()
4145 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004146
4147 def transactionalMapGet( self, keyName, inMemory=False ):
4148 """
4149 CLI command to get the value of a key in a consistent map using
4150 transactions. This a test function and can only get keys from the
4151 test map hard coded into the cli command
4152 Required arguments:
4153 keyName - The name of the key to get
4154 Optional arguments:
4155 inMemory - use in memory map for the counter
4156 returns:
4157 The string value of the key or
4158 None on Error
4159 """
4160 try:
4161 keyName = str( keyName )
4162 cmdStr = "transactional-map-test-get "
4163 if inMemory:
4164 cmdStr += "-i "
4165 cmdStr += keyName
4166 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004167 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004168 try:
4169 # TODO: Maybe make this less hardcoded
4170 # ConsistentMap Exceptions
4171 assert "org.onosproject.store.service" not in output
4172 # Node not leader
4173 assert "java.lang.IllegalStateException" not in output
4174 except AssertionError:
4175 main.log.error( "Error in processing '" + cmdStr + "' " +
4176 "command: " + str( output ) )
4177 return None
4178 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4179 if "Key " + keyName + " not found." in output:
4180 return None
4181 else:
4182 match = re.search( pattern, output )
4183 if match:
4184 return match.groupdict()[ 'value' ]
4185 else:
4186 main.log.error( self.name + ": transactionlMapGet did not" +
4187 " match expected output." )
4188 main.log.debug( self.name + " expected: " + pattern )
4189 main.log.debug( self.name + " actual: " + repr( output ) )
4190 return None
Jon Hallc6793552016-01-19 14:18:37 -08004191 except AssertionError:
4192 main.log.exception( "" )
4193 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004194 except TypeError:
4195 main.log.exception( self.name + ": Object not as expected" )
4196 return None
4197 except pexpect.EOF:
4198 main.log.error( self.name + ": EOF exception found" )
4199 main.log.error( self.name + ": " + self.handle.before )
4200 main.cleanup()
4201 main.exit()
4202 except Exception:
4203 main.log.exception( self.name + ": Uncaught exception!" )
4204 main.cleanup()
4205 main.exit()
4206
4207 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4208 """
4209 CLI command to put a value into 'numKeys' number of keys in a
4210 consistent map using transactions. This a test function and can only
4211 put into keys named 'Key#' of the test map hard coded into the cli command
4212 Required arguments:
4213 numKeys - Number of keys to add the value to
4214 value - The string value to put into the keys
4215 Optional arguments:
4216 inMemory - use in memory map for the counter
4217 returns:
4218 A dictionary whose keys are the name of the keys put into the map
4219 and the values of the keys are dictionaries whose key-values are
4220 'value': value put into map and optionaly
4221 'oldValue': Previous value in the key or
4222 None on Error
4223
4224 Example output
4225 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4226 'Key2': {'value': 'Testing'} }
4227 """
4228 try:
4229 numKeys = str( numKeys )
4230 value = str( value )
4231 cmdStr = "transactional-map-test-put "
4232 if inMemory:
4233 cmdStr += "-i "
4234 cmdStr += numKeys + " " + value
4235 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004236 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004237 try:
4238 # TODO: Maybe make this less hardcoded
4239 # ConsistentMap Exceptions
4240 assert "org.onosproject.store.service" not in output
4241 # Node not leader
4242 assert "java.lang.IllegalStateException" not in output
4243 except AssertionError:
4244 main.log.error( "Error in processing '" + cmdStr + "' " +
4245 "command: " + str( output ) )
4246 return None
4247 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4248 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4249 results = {}
4250 for line in output.splitlines():
4251 new = re.search( newPattern, line )
4252 updated = re.search( updatedPattern, line )
4253 if new:
4254 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4255 elif updated:
4256 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004257 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004258 else:
4259 main.log.error( self.name + ": transactionlMapGet did not" +
4260 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004261 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4262 newPattern,
4263 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004264 main.log.debug( self.name + " actual: " + repr( output ) )
4265 return results
Jon Hallc6793552016-01-19 14:18:37 -08004266 except AssertionError:
4267 main.log.exception( "" )
4268 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004269 except TypeError:
4270 main.log.exception( self.name + ": Object not as expected" )
4271 return None
4272 except pexpect.EOF:
4273 main.log.error( self.name + ": EOF exception found" )
4274 main.log.error( self.name + ": " + self.handle.before )
4275 main.cleanup()
4276 main.exit()
4277 except Exception:
4278 main.log.exception( self.name + ": Uncaught exception!" )
4279 main.cleanup()
4280 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004281
acsmarsdaea66c2015-09-03 11:44:06 -07004282 def maps( self, jsonFormat=True ):
4283 """
4284 Description: Returns result of onos:maps
4285 Optional:
4286 * jsonFormat: enable json formatting of output
4287 """
4288 try:
4289 cmdStr = "maps"
4290 if jsonFormat:
4291 cmdStr += " -j"
4292 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004293 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004294 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004295 except AssertionError:
4296 main.log.exception( "" )
4297 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004298 except TypeError:
4299 main.log.exception( self.name + ": Object not as expected" )
4300 return None
4301 except pexpect.EOF:
4302 main.log.error( self.name + ": EOF exception found" )
4303 main.log.error( self.name + ": " + self.handle.before )
4304 main.cleanup()
4305 main.exit()
4306 except Exception:
4307 main.log.exception( self.name + ": Uncaught exception!" )
4308 main.cleanup()
4309 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004310
4311 def getSwController( self, uri, jsonFormat=True ):
4312 """
4313 Descrition: Gets the controller information from the device
4314 """
4315 try:
4316 cmd = "device-controllers "
4317 if jsonFormat:
4318 cmd += "-j "
4319 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004320 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004321 return response
Jon Hallc6793552016-01-19 14:18:37 -08004322 except AssertionError:
4323 main.log.exception( "" )
4324 return None
GlennRC050596c2015-11-18 17:06:41 -08004325 except TypeError:
4326 main.log.exception( self.name + ": Object not as expected" )
4327 return None
4328 except pexpect.EOF:
4329 main.log.error( self.name + ": EOF exception found" )
4330 main.log.error( self.name + ": " + self.handle.before )
4331 main.cleanup()
4332 main.exit()
4333 except Exception:
4334 main.log.exception( self.name + ": Uncaught exception!" )
4335 main.cleanup()
4336 main.exit()
4337
4338 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4339 """
4340 Descrition: sets the controller(s) for the specified device
4341
4342 Parameters:
4343 Required: uri - String: The uri of the device(switch).
4344 ip - String or List: The ip address of the controller.
4345 This parameter can be formed in a couple of different ways.
4346 VALID:
4347 10.0.0.1 - just the ip address
4348 tcp:10.0.0.1 - the protocol and the ip address
4349 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4350 so that you can add controllers with different
4351 protocols and ports
4352 INVALID:
4353 10.0.0.1:6653 - this is not supported by ONOS
4354
4355 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4356 port - The port number.
4357 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4358
4359 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4360 """
4361 try:
4362 cmd = "device-setcontrollers"
4363
4364 if jsonFormat:
4365 cmd += " -j"
4366 cmd += " " + uri
4367 if isinstance( ip, str ):
4368 ip = [ip]
4369 for item in ip:
4370 if ":" in item:
4371 sitem = item.split( ":" )
4372 if len(sitem) == 3:
4373 cmd += " " + item
4374 elif "." in sitem[1]:
4375 cmd += " {}:{}".format(item, port)
4376 else:
4377 main.log.error( "Malformed entry: " + item )
4378 raise TypeError
4379 else:
4380 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004381 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004382 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004383 if "Error" in response:
4384 main.log.error( response )
4385 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004386 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004387 except AssertionError:
4388 main.log.exception( "" )
4389 return None
GlennRC050596c2015-11-18 17:06:41 -08004390 except TypeError:
4391 main.log.exception( self.name + ": Object not as expected" )
4392 return main.FALSE
4393 except pexpect.EOF:
4394 main.log.error( self.name + ": EOF exception found" )
4395 main.log.error( self.name + ": " + self.handle.before )
4396 main.cleanup()
4397 main.exit()
4398 except Exception:
4399 main.log.exception( self.name + ": Uncaught exception!" )
4400 main.cleanup()
4401 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004402
4403 def removeDevice( self, device ):
4404 '''
4405 Description:
4406 Remove a device from ONOS by passing the uri of the device(s).
4407 Parameters:
4408 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4409 Returns:
4410 Returns main.FALSE if an exception is thrown or an error is present
4411 in the response. Otherwise, returns main.TRUE.
4412 NOTE:
4413 If a host cannot be removed, then this function will return main.FALSE
4414 '''
4415 try:
4416 if type( device ) is str:
4417 device = list( device )
4418
4419 for d in device:
4420 time.sleep( 1 )
4421 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004422 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004423 if "Error" in response:
4424 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4425 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004426 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004427 except AssertionError:
4428 main.log.exception( "" )
4429 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004430 except TypeError:
4431 main.log.exception( self.name + ": Object not as expected" )
4432 return main.FALSE
4433 except pexpect.EOF:
4434 main.log.error( self.name + ": EOF exception found" )
4435 main.log.error( self.name + ": " + self.handle.before )
4436 main.cleanup()
4437 main.exit()
4438 except Exception:
4439 main.log.exception( self.name + ": Uncaught exception!" )
4440 main.cleanup()
4441 main.exit()
4442
4443 def removeHost( self, host ):
4444 '''
4445 Description:
4446 Remove a host from ONOS by passing the id of the host(s)
4447 Parameters:
4448 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4449 Returns:
4450 Returns main.FALSE if an exception is thrown or an error is present
4451 in the response. Otherwise, returns main.TRUE.
4452 NOTE:
4453 If a host cannot be removed, then this function will return main.FALSE
4454 '''
4455 try:
4456 if type( host ) is str:
4457 host = list( host )
4458
4459 for h in host:
4460 time.sleep( 1 )
4461 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004462 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004463 if "Error" in response:
4464 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4465 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004466 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004467 except AssertionError:
4468 main.log.exception( "" )
4469 return None
GlennRC20fc6522015-12-23 23:26:57 -08004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return main.FALSE
4473 except pexpect.EOF:
4474 main.log.error( self.name + ": EOF exception found" )
4475 main.log.error( self.name + ": " + self.handle.before )
4476 main.cleanup()
4477 main.exit()
4478 except Exception:
4479 main.log.exception( self.name + ": Uncaught exception!" )
4480 main.cleanup()
4481 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004482
Jon Hallc6793552016-01-19 14:18:37 -08004483 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004484 '''
4485 Description:
4486 Bring link down or up in the null-provider.
4487 params:
4488 begin - (string) One end of a device or switch.
4489 end - (string) the other end of the device or switch
4490 returns:
4491 main.TRUE if no exceptions were thrown and no Errors are
4492 present in the resoponse. Otherwise, returns main.FALSE
4493 '''
4494 try:
Jon Hallc6793552016-01-19 14:18:37 -08004495 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004496 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004497 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004498 if "Error" in response or "Failure" in response:
4499 main.log.error( response )
4500 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004501 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004502 except AssertionError:
4503 main.log.exception( "" )
4504 return None
GlennRCed771242016-01-13 17:02:47 -08004505 except TypeError:
4506 main.log.exception( self.name + ": Object not as expected" )
4507 return main.FALSE
4508 except pexpect.EOF:
4509 main.log.error( self.name + ": EOF exception found" )
4510 main.log.error( self.name + ": " + self.handle.before )
4511 main.cleanup()
4512 main.exit()
4513 except Exception:
4514 main.log.exception( self.name + ": Uncaught exception!" )
4515 main.cleanup()
4516 main.exit()
4517