blob: 16f22089de993965a88fd7bcbccf965976994682 [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
YPZhangb5d3f832016-01-23 22:54:26 -08002200 def getTotalFlowsNum( self ):
2201 """
2202 Description:
2203 Get the total number of flows, include every states.
2204 Return:
2205 The number of flows
2206 """
2207 try:
2208 cmd = "summary -j"
2209 response = self.sendline( cmd )
2210 if response == None:
2211 return -1
2212 response = json.loads( response )
2213 return int( response.get("flows") )
2214 except TypeError:
2215 main.log.exception( self.name + ": Object not as expected" )
2216 return None
2217 except pexpect.EOF:
2218 main.log.error( self.name + ": EOF exception found" )
2219 main.log.error( self.name + ": " + self.handle.before )
2220 main.cleanup()
2221 main.exit()
2222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
2224 main.cleanup()
2225 main.exit()
2226
2227 def getTotalIntentsNum( self ):
2228 """
2229 Description:
2230 Get the total number of intents, include every states.
2231 Return:
2232 The number of intents
2233 """
2234 try:
2235 cmd = "summary -j"
2236 response = self.sendline( cmd )
2237 if response == None:
2238 return -1
2239 response = json.loads( response )
2240 return int( response.get("intents") )
2241 except TypeError:
2242 main.log.exception( self.name + ": Object not as expected" )
2243 return None
2244 except pexpect.EOF:
2245 main.log.error( self.name + ": EOF exception found" )
2246 main.log.error( self.name + ": " + self.handle.before )
2247 main.cleanup()
2248 main.exit()
2249 except Exception:
2250 main.log.exception( self.name + ": Uncaught exception!" )
2251 main.cleanup()
2252 main.exit()
2253
kelvin-onlabd3b64892015-01-20 13:26:24 -08002254 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002255 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002256 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002257 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002259 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002260 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002261 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002262 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002263 cmdStr += " -j"
2264 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002265 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002266 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002267 except AssertionError:
2268 main.log.exception( "" )
2269 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002270 except TypeError:
2271 main.log.exception( self.name + ": Object not as expected" )
2272 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002273 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002274 main.log.error( self.name + ": EOF exception found" )
2275 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002276 main.cleanup()
2277 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002278 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002279 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002280 main.cleanup()
2281 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002282
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002284 """
2285 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002286 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002287 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002288 """
andrewonlab867212a2014-10-22 20:13:38 -04002289 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002290 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002292 cmdStr += " -j"
2293 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002294 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002295 if handle:
2296 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002297 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002298 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002299 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002300 else:
2301 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002302 except AssertionError:
2303 main.log.exception( "" )
2304 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002305 except TypeError:
2306 main.log.exception( self.name + ": Object not as expected" )
2307 return None
andrewonlab867212a2014-10-22 20:13:38 -04002308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002309 main.log.error( self.name + ": EOF exception found" )
2310 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002311 main.cleanup()
2312 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002313 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002314 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002315 main.cleanup()
2316 main.exit()
2317
kelvin8ec71442015-01-15 16:57:00 -08002318 # Wrapper functions ****************
2319 # Wrapper functions use existing driver
2320 # functions and extends their use case.
2321 # For example, we may use the output of
2322 # a normal driver function, and parse it
2323 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002324
kelvin-onlabd3b64892015-01-20 13:26:24 -08002325 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002326 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002327 Description:
2328 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002329 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002330 try:
kelvin8ec71442015-01-15 16:57:00 -08002331 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002332 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002333 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002334
kelvin8ec71442015-01-15 16:57:00 -08002335 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002336 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2337 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002338 match = re.search('id=0x([\da-f]+),', intents)
2339 if match:
2340 tmpId = match.group()[3:-1]
2341 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002342 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002343
Jon Halld4d4b372015-01-28 16:02:41 -08002344 except TypeError:
2345 main.log.exception( self.name + ": Object not as expected" )
2346 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002348 main.log.error( self.name + ": EOF exception found" )
2349 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002350 main.cleanup()
2351 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002352 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002353 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002354 main.cleanup()
2355 main.exit()
2356
Jon Hall30b82fa2015-03-04 17:15:43 -08002357 def FlowAddedCount( self, deviceId ):
2358 """
2359 Determine the number of flow rules for the given device id that are
2360 in the added state
2361 """
2362 try:
2363 cmdStr = "flows any " + str( deviceId ) + " | " +\
2364 "grep 'state=ADDED' | wc -l"
2365 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002366 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002367 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002368 except AssertionError:
2369 main.log.exception( "" )
2370 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002371 except pexpect.EOF:
2372 main.log.error( self.name + ": EOF exception found" )
2373 main.log.error( self.name + ": " + self.handle.before )
2374 main.cleanup()
2375 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002376 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002377 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002378 main.cleanup()
2379 main.exit()
2380
kelvin-onlabd3b64892015-01-20 13:26:24 -08002381 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002382 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002383 Use 'devices' function to obtain list of all devices
2384 and parse the result to obtain a list of all device
2385 id's. Returns this list. Returns empty list if no
2386 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002387 List is ordered sequentially
2388
andrewonlab3e15ead2014-10-15 14:21:34 -04002389 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002390 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002391 the ids. By obtaining the list of device ids on the fly,
2392 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002393 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002394 try:
kelvin8ec71442015-01-15 16:57:00 -08002395 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002396 devicesStr = self.devices( jsonFormat=False )
2397 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002398
kelvin-onlabd3b64892015-01-20 13:26:24 -08002399 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002400 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002401 return idList
kelvin8ec71442015-01-15 16:57:00 -08002402
2403 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002404 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002405 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002406 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002407 # Split list further into arguments before and after string
2408 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002409 # append to idList
2410 for arg in tempList:
2411 idList.append( arg.split( "id=" )[ 1 ] )
2412 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002413
Jon Halld4d4b372015-01-28 16:02:41 -08002414 except TypeError:
2415 main.log.exception( self.name + ": Object not as expected" )
2416 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002417 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002418 main.log.error( self.name + ": EOF exception found" )
2419 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002420 main.cleanup()
2421 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002422 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002423 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002424 main.cleanup()
2425 main.exit()
2426
kelvin-onlabd3b64892015-01-20 13:26:24 -08002427 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002428 """
andrewonlab7c211572014-10-15 16:45:20 -04002429 Uses 'nodes' function to obtain list of all nodes
2430 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002431 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002432 Returns:
2433 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002434 """
andrewonlab7c211572014-10-15 16:45:20 -04002435 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002436 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002437 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002438 # Sample nodesStr output
2439 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002440 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002441 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002442 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002443 nodesJson = json.loads( nodesStr )
2444 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002445 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002446 except ( TypeError, ValueError ):
2447 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002448 return None
andrewonlab7c211572014-10-15 16:45:20 -04002449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002452 main.cleanup()
2453 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002454 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002455 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002456 main.cleanup()
2457 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002458
kelvin-onlabd3b64892015-01-20 13:26:24 -08002459 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002460 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002461 Return the first device from the devices api whose 'id' contains 'dpid'
2462 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002463 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002464 try:
kelvin8ec71442015-01-15 16:57:00 -08002465 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002466 return None
2467 else:
kelvin8ec71442015-01-15 16:57:00 -08002468 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002469 rawDevices = self.devices()
2470 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002471 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002472 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002473 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2474 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002475 return device
2476 return None
Jon Hallc6793552016-01-19 14:18:37 -08002477 except ( TypeError, ValueError ):
2478 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002479 return None
Jon Halla91c4dc2014-10-22 12:57:04 -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 )
Jon Halla91c4dc2014-10-22 12:57:04 -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!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002487 main.cleanup()
2488 main.exit()
2489
kelvin-onlabd3b64892015-01-20 13:26:24 -08002490 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002491 """
Jon Hallefbd9792015-03-05 16:11:36 -08002492 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002493 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002494 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002495
Jon Hall42db6dc2014-10-24 19:03:48 -04002496 Params: ip = ip used for the onos cli
2497 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002498 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002499 logLevel = level to log to. Currently accepts
2500 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002501
2502
kelvin-onlabd3b64892015-01-20 13:26:24 -08002503 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002504
Jon Hallefbd9792015-03-05 16:11:36 -08002505 Returns: main.TRUE if the number of switches and links are correct,
2506 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002507 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002508 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002509 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002511 if topology == {}:
2512 return main.ERROR
2513 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002514 # Is the number of switches is what we expected
2515 devices = topology.get( 'devices', False )
2516 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002517 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002518 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002519 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002520 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002521 linkCheck = ( int( links ) == int( numolink ) )
2522 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002523 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002524 output += "The number of links and switches match " +\
2525 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002526 result = main.TRUE
2527 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002528 output += "The number of links and switches does not match " +\
2529 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002530 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002531 output = output + "\n ONOS sees %i devices (%i expected) \
2532 and %i links (%i expected)" % (
2533 int( devices ), int( numoswitch ), int( links ),
2534 int( numolink ) )
2535 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002536 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002537 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002538 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002539 else:
Jon Hall390696c2015-05-05 17:13:41 -07002540 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002541 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002542 except TypeError:
2543 main.log.exception( self.name + ": Object not as expected" )
2544 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002545 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002546 main.log.error( self.name + ": EOF exception found" )
2547 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002548 main.cleanup()
2549 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002551 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002552 main.cleanup()
2553 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002554
kelvin-onlabd3b64892015-01-20 13:26:24 -08002555 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002556 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002557 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002558 deviceId must be the id of a device as seen in the onos devices command
2559 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002560 role must be either master, standby, or none
2561
Jon Halle3f39ff2015-01-13 11:50:53 -08002562 Returns:
2563 main.TRUE or main.FALSE based on argument verification and
2564 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002565 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002566 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002567 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002568 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002569 cmdStr = "device-role " +\
2570 str( deviceId ) + " " +\
2571 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002572 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002573 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002574 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002575 if re.search( "Error", handle ):
2576 # end color output to escape any colours
2577 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002578 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002579 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002580 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002581 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002582 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002583 main.log.error( "Invalid 'role' given to device_role(). " +
2584 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002585 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002586 except AssertionError:
2587 main.log.exception( "" )
2588 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002589 except TypeError:
2590 main.log.exception( self.name + ": Object not as expected" )
2591 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002593 main.log.error( self.name + ": EOF exception found" )
2594 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002595 main.cleanup()
2596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002598 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002599 main.cleanup()
2600 main.exit()
2601
kelvin-onlabd3b64892015-01-20 13:26:24 -08002602 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002603 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002604 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002605 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002606 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002607 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002608 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002609 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002610 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002611 cmdStr += " -j"
2612 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002613 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002614 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002615 except AssertionError:
2616 main.log.exception( "" )
2617 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002618 except TypeError:
2619 main.log.exception( self.name + ": Object not as expected" )
2620 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002621 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002622 main.log.error( self.name + ": EOF exception found" )
2623 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002624 main.cleanup()
2625 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002626 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002627 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002628 main.cleanup()
2629 main.exit()
2630
kelvin-onlabd3b64892015-01-20 13:26:24 -08002631 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002632 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002633 CLI command to get the current leader for the Election test application
2634 NOTE: Requires installation of the onos-app-election feature
2635 Returns: Node IP of the leader if one exists
2636 None if none exists
2637 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002638 """
Jon Hall94fd0472014-12-08 11:52:42 -08002639 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 cmdStr = "election-test-leader"
2641 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002642 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002643 # Leader
2644 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002645 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 nodeSearch = re.search( leaderPattern, response )
2647 if nodeSearch:
2648 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002649 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002650 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002651 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002652 # no leader
2653 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002654 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002655 nullSearch = re.search( nullPattern, response )
2656 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002657 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002658 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002659 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002660 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002661 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002662 if re.search( errorPattern, response ):
2663 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002664 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002665 return main.FALSE
2666 else:
Jon Hall390696c2015-05-05 17:13:41 -07002667 main.log.error( "Error in electionTestLeader on " + self.name +
2668 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002669 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002670 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002671 except AssertionError:
2672 main.log.exception( "" )
2673 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002674 except TypeError:
2675 main.log.exception( self.name + ": Object not as expected" )
2676 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002677 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002678 main.log.error( self.name + ": EOF exception found" )
2679 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002680 main.cleanup()
2681 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002682 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002683 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002684 main.cleanup()
2685 main.exit()
2686
kelvin-onlabd3b64892015-01-20 13:26:24 -08002687 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002688 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002689 CLI command to run for leadership of the Election test application.
2690 NOTE: Requires installation of the onos-app-election feature
2691 Returns: Main.TRUE on success
2692 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002693 """
Jon Hall94fd0472014-12-08 11:52:42 -08002694 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002695 cmdStr = "election-test-run"
2696 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002697 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002698 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002699 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002700 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002701 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002702 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002703 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002704 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002705 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002706 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002707 errorPattern = "Command\snot\sfound"
2708 if re.search( errorPattern, response ):
2709 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002710 return main.FALSE
2711 else:
Jon Hall390696c2015-05-05 17:13:41 -07002712 main.log.error( "Error in electionTestRun on " + self.name +
2713 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002714 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002715 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002716 except AssertionError:
2717 main.log.exception( "" )
2718 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002719 except TypeError:
2720 main.log.exception( self.name + ": Object not as expected" )
2721 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002723 main.log.error( self.name + ": EOF exception found" )
2724 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002725 main.cleanup()
2726 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002727 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002728 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002729 main.cleanup()
2730 main.exit()
2731
kelvin-onlabd3b64892015-01-20 13:26:24 -08002732 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002733 """
Jon Hall94fd0472014-12-08 11:52:42 -08002734 * CLI command to withdraw the local node from leadership election for
2735 * the Election test application.
2736 #NOTE: Requires installation of the onos-app-election feature
2737 Returns: Main.TRUE on success
2738 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002739 """
Jon Hall94fd0472014-12-08 11:52:42 -08002740 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002741 cmdStr = "election-test-withdraw"
2742 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002743 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002744 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002745 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002746 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002747 if re.search( successPattern, response ):
2748 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002749 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002750 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002751 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002752 errorPattern = "Command\snot\sfound"
2753 if re.search( errorPattern, response ):
2754 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002755 return main.FALSE
2756 else:
Jon Hall390696c2015-05-05 17:13:41 -07002757 main.log.error( "Error in electionTestWithdraw on " +
2758 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002759 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002760 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002761 except AssertionError:
2762 main.log.exception( "" )
2763 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002764 except TypeError:
2765 main.log.exception( self.name + ": Object not as expected" )
2766 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002770 main.cleanup()
2771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002773 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002774 main.cleanup()
2775 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002776
kelvin8ec71442015-01-15 16:57:00 -08002777 def getDevicePortsEnabledCount( self, dpid ):
2778 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002779 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002780 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002781 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002782 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2784 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002785 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002786 if re.search( "No such device", output ):
2787 main.log.error( "Error in getting ports" )
2788 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002789 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002790 return output
Jon Hallc6793552016-01-19 14:18:37 -08002791 except AssertionError:
2792 main.log.exception( "" )
2793 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002794 except TypeError:
2795 main.log.exception( self.name + ": Object not as expected" )
2796 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002797 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002798 main.log.error( self.name + ": EOF exception found" )
2799 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002800 main.cleanup()
2801 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002802 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002803 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002804 main.cleanup()
2805 main.exit()
2806
kelvin8ec71442015-01-15 16:57:00 -08002807 def getDeviceLinksActiveCount( self, dpid ):
2808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002809 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002810 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002811 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002812 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2814 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002815 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002816 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002817 main.log.error( "Error in getting ports " )
2818 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002819 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002820 return output
Jon Hallc6793552016-01-19 14:18:37 -08002821 except AssertionError:
2822 main.log.exception( "" )
2823 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002824 except TypeError:
2825 main.log.exception( self.name + ": Object not as expected" )
2826 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002827 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002828 main.log.error( self.name + ": EOF exception found" )
2829 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002830 main.cleanup()
2831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002832 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002833 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002834 main.cleanup()
2835 main.exit()
2836
kelvin8ec71442015-01-15 16:57:00 -08002837 def getAllIntentIds( self ):
2838 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002839 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002840 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002841 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002842 cmdStr = "onos:intents | grep id="
2843 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002844 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002845 if re.search( "Error", output ):
2846 main.log.error( "Error in getting ports" )
2847 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002848 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002849 return output
Jon Hallc6793552016-01-19 14:18:37 -08002850 except AssertionError:
2851 main.log.exception( "" )
2852 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002853 except TypeError:
2854 main.log.exception( self.name + ": Object not as expected" )
2855 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002856 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002857 main.log.error( self.name + ": EOF exception found" )
2858 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002859 main.cleanup()
2860 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002861 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002862 main.log.exception( self.name + ": Uncaught exception!" )
2863 main.cleanup()
2864 main.exit()
2865
Jon Hall73509952015-02-24 16:42:56 -08002866 def intentSummary( self ):
2867 """
Jon Hallefbd9792015-03-05 16:11:36 -08002868 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002869 """
2870 try:
2871 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002872 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002873 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002874 states.append( intent.get( 'state', None ) )
2875 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002876 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002877 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002878 except ( TypeError, ValueError ):
2879 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002880 return None
2881 except pexpect.EOF:
2882 main.log.error( self.name + ": EOF exception found" )
2883 main.log.error( self.name + ": " + self.handle.before )
2884 main.cleanup()
2885 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002886 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002887 main.log.exception( self.name + ": Uncaught exception!" )
2888 main.cleanup()
2889 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002890
Jon Hall61282e32015-03-19 11:34:11 -07002891 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002892 """
2893 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002894 Optional argument:
2895 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002896 """
Jon Hall63604932015-02-26 17:09:50 -08002897 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002898 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002899 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002900 cmdStr += " -j"
2901 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002902 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002903 return output
Jon Hallc6793552016-01-19 14:18:37 -08002904 except AssertionError:
2905 main.log.exception( "" )
2906 return None
Jon Hall63604932015-02-26 17:09:50 -08002907 except TypeError:
2908 main.log.exception( self.name + ": Object not as expected" )
2909 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002910 except pexpect.EOF:
2911 main.log.error( self.name + ": EOF exception found" )
2912 main.log.error( self.name + ": " + self.handle.before )
2913 main.cleanup()
2914 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002915 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002916 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002917 main.cleanup()
2918 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002919
acsmarsa4a4d1e2015-07-10 16:01:24 -07002920 def leaderCandidates( self, jsonFormat=True ):
2921 """
2922 Returns the output of the leaders -c command.
2923 Optional argument:
2924 * jsonFormat - boolean indicating if you want output in json
2925 """
2926 try:
2927 cmdStr = "onos:leaders -c"
2928 if jsonFormat:
2929 cmdStr += " -j"
2930 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002931 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002932 return output
Jon Hallc6793552016-01-19 14:18:37 -08002933 except AssertionError:
2934 main.log.exception( "" )
2935 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002936 except TypeError:
2937 main.log.exception( self.name + ": Object not as expected" )
2938 return None
2939 except pexpect.EOF:
2940 main.log.error( self.name + ": EOF exception found" )
2941 main.log.error( self.name + ": " + self.handle.before )
2942 main.cleanup()
2943 main.exit()
2944 except Exception:
2945 main.log.exception( self.name + ": Uncaught exception!" )
2946 main.cleanup()
2947 main.exit()
2948
Jon Hallc6793552016-01-19 14:18:37 -08002949 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002950 """
2951 Returns a list in format [leader,candidate1,candidate2,...] for a given
2952 topic parameter and an empty list if the topic doesn't exist
2953 If no leader is elected leader in the returned list will be "none"
2954 Returns None if there is a type error processing the json object
2955 """
2956 try:
2957 cmdStr = "onos:leaders -c -j"
Jon Hallc6793552016-01-19 14:18:37 -08002958 rawOutput = self.sendline( cmdStr )
2959 assert "Command not found:" not in rawOutput, rawOutput
2960 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002961 results = []
2962 for dict in output:
2963 if dict["topic"] == topic:
2964 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002965 candidates = re.split( ", ", dict["candidates"][1:-1] )
2966 results.append( leader )
2967 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002968 return results
Jon Hallc6793552016-01-19 14:18:37 -08002969 except AssertionError:
2970 main.log.exception( "" )
2971 return None
2972 except ( TypeError, ValueError ):
2973 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002974 return None
2975 except pexpect.EOF:
2976 main.log.error( self.name + ": EOF exception found" )
2977 main.log.error( self.name + ": " + self.handle.before )
2978 main.cleanup()
2979 main.exit()
2980 except Exception:
2981 main.log.exception( self.name + ": Uncaught exception!" )
2982 main.cleanup()
2983 main.exit()
2984
Jon Hall61282e32015-03-19 11:34:11 -07002985 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002986 """
2987 Returns the output of the intent Pending map.
2988 """
Jon Hall63604932015-02-26 17:09:50 -08002989 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002990 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002991 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002992 cmdStr += " -j"
2993 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002994 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002995 return output
Jon Hallc6793552016-01-19 14:18:37 -08002996 except AssertionError:
2997 main.log.exception( "" )
2998 return None
Jon Hall63604932015-02-26 17:09:50 -08002999 except TypeError:
3000 main.log.exception( self.name + ": Object not as expected" )
3001 return None
3002 except pexpect.EOF:
3003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
3005 main.cleanup()
3006 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003007 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003008 main.log.exception( self.name + ": Uncaught exception!" )
3009 main.cleanup()
3010 main.exit()
3011
Jon Hall61282e32015-03-19 11:34:11 -07003012 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003013 """
3014 Returns the output of the raft partitions command for ONOS.
3015 """
Jon Hall61282e32015-03-19 11:34:11 -07003016 # Sample JSON
3017 # {
3018 # "leader": "tcp://10.128.30.11:7238",
3019 # "members": [
3020 # "tcp://10.128.30.11:7238",
3021 # "tcp://10.128.30.17:7238",
3022 # "tcp://10.128.30.13:7238",
3023 # ],
3024 # "name": "p1",
3025 # "term": 3
3026 # },
Jon Hall63604932015-02-26 17:09:50 -08003027 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003028 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003029 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003030 cmdStr += " -j"
3031 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003032 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003033 return output
Jon Hallc6793552016-01-19 14:18:37 -08003034 except AssertionError:
3035 main.log.exception( "" )
3036 return None
Jon Hall63604932015-02-26 17:09:50 -08003037 except TypeError:
3038 main.log.exception( self.name + ": Object not as expected" )
3039 return None
3040 except pexpect.EOF:
3041 main.log.error( self.name + ": EOF exception found" )
3042 main.log.error( self.name + ": " + self.handle.before )
3043 main.cleanup()
3044 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003045 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003046 main.log.exception( self.name + ": Uncaught exception!" )
3047 main.cleanup()
3048 main.exit()
3049
Jon Hallbe379602015-03-24 13:39:32 -07003050 def apps( self, jsonFormat=True ):
3051 """
3052 Returns the output of the apps command for ONOS. This command lists
3053 information about installed ONOS applications
3054 """
3055 # Sample JSON object
3056 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3057 # "description":"ONOS OpenFlow protocol southbound providers",
3058 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3059 # "features":"[onos-openflow]","state":"ACTIVE"}]
3060 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003061 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003062 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003063 cmdStr += " -j"
3064 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003065 assert "Command not found:" not in output, output
3066 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003067 return output
Jon Hallbe379602015-03-24 13:39:32 -07003068 # FIXME: look at specific exceptions/Errors
3069 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003070 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003071 return None
3072 except TypeError:
3073 main.log.exception( self.name + ": Object not as expected" )
3074 return None
3075 except pexpect.EOF:
3076 main.log.error( self.name + ": EOF exception found" )
3077 main.log.error( self.name + ": " + self.handle.before )
3078 main.cleanup()
3079 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003080 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003081 main.log.exception( self.name + ": Uncaught exception!" )
3082 main.cleanup()
3083 main.exit()
3084
Jon Hall146f1522015-03-24 15:33:24 -07003085 def appStatus( self, appName ):
3086 """
3087 Uses the onos:apps cli command to return the status of an application.
3088 Returns:
3089 "ACTIVE" - If app is installed and activated
3090 "INSTALLED" - If app is installed and deactivated
3091 "UNINSTALLED" - If app is not installed
3092 None - on error
3093 """
Jon Hall146f1522015-03-24 15:33:24 -07003094 try:
3095 if not isinstance( appName, types.StringType ):
3096 main.log.error( self.name + ".appStatus(): appName must be" +
3097 " a string" )
3098 return None
3099 output = self.apps( jsonFormat=True )
3100 appsJson = json.loads( output )
3101 state = None
3102 for app in appsJson:
3103 if appName == app.get('name'):
3104 state = app.get('state')
3105 break
3106 if state == "ACTIVE" or state == "INSTALLED":
3107 return state
3108 elif state is None:
3109 return "UNINSTALLED"
3110 elif state:
3111 main.log.error( "Unexpected state from 'onos:apps': " +
3112 str( state ) )
3113 return state
Jon Hallc6793552016-01-19 14:18:37 -08003114 except ( TypeError, ValueError ):
3115 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3116 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003117 return None
3118 except pexpect.EOF:
3119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
3121 main.cleanup()
3122 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003123 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003124 main.log.exception( self.name + ": Uncaught exception!" )
3125 main.cleanup()
3126 main.exit()
3127
Jon Hallbe379602015-03-24 13:39:32 -07003128 def app( self, appName, option ):
3129 """
3130 Interacts with the app command for ONOS. This command manages
3131 application inventory.
3132 """
Jon Hallbe379602015-03-24 13:39:32 -07003133 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003134 # Validate argument types
3135 valid = True
3136 if not isinstance( appName, types.StringType ):
3137 main.log.error( self.name + ".app(): appName must be a " +
3138 "string" )
3139 valid = False
3140 if not isinstance( option, types.StringType ):
3141 main.log.error( self.name + ".app(): option must be a string" )
3142 valid = False
3143 if not valid:
3144 return main.FALSE
3145 # Validate Option
3146 option = option.lower()
3147 # NOTE: Install may become a valid option
3148 if option == "activate":
3149 pass
3150 elif option == "deactivate":
3151 pass
3152 elif option == "uninstall":
3153 pass
3154 else:
3155 # Invalid option
3156 main.log.error( "The ONOS app command argument only takes " +
3157 "the values: (activate|deactivate|uninstall)" +
3158 "; was given '" + option + "'")
3159 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003160 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003161 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003162 if "Error executing command" in output:
3163 main.log.error( "Error in processing onos:app command: " +
3164 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003165 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003166 elif "No such application" in output:
3167 main.log.error( "The application '" + appName +
3168 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003169 return main.FALSE
3170 elif "Command not found:" in output:
3171 main.log.error( "Error in processing onos:app command: " +
3172 str( output ) )
3173 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003174 elif "Unsupported command:" in output:
3175 main.log.error( "Incorrect command given to 'app': " +
3176 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003177 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003178 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003179 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003180 return main.TRUE
3181 except TypeError:
3182 main.log.exception( self.name + ": Object not as expected" )
3183 return main.ERROR
3184 except pexpect.EOF:
3185 main.log.error( self.name + ": EOF exception found" )
3186 main.log.error( self.name + ": " + self.handle.before )
3187 main.cleanup()
3188 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003189 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003190 main.log.exception( self.name + ": Uncaught exception!" )
3191 main.cleanup()
3192 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003193
Jon Hallbd16b922015-03-26 17:53:15 -07003194 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003195 """
3196 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003197 appName is the hierarchical app name, not the feature name
3198 If check is True, method will check the status of the app after the
3199 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003200 Returns main.TRUE if the command was successfully sent
3201 main.FALSE if the cli responded with an error or given
3202 incorrect input
3203 """
3204 try:
3205 if not isinstance( appName, types.StringType ):
3206 main.log.error( self.name + ".activateApp(): appName must be" +
3207 " a string" )
3208 return main.FALSE
3209 status = self.appStatus( appName )
3210 if status == "INSTALLED":
3211 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003212 if check and response == main.TRUE:
3213 for i in range(10): # try 10 times then give up
3214 # TODO: Check with Thomas about this delay
3215 status = self.appStatus( appName )
3216 if status == "ACTIVE":
3217 return main.TRUE
3218 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003219 main.log.debug( "The state of application " +
3220 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003221 time.sleep( 1 )
3222 return main.FALSE
3223 else: # not 'check' or command didn't succeed
3224 return response
Jon Hall146f1522015-03-24 15:33:24 -07003225 elif status == "ACTIVE":
3226 return main.TRUE
3227 elif status == "UNINSTALLED":
3228 main.log.error( self.name + ": Tried to activate the " +
3229 "application '" + appName + "' which is not " +
3230 "installed." )
3231 else:
3232 main.log.error( "Unexpected return value from appStatus: " +
3233 str( status ) )
3234 return main.ERROR
3235 except TypeError:
3236 main.log.exception( self.name + ": Object not as expected" )
3237 return main.ERROR
3238 except pexpect.EOF:
3239 main.log.error( self.name + ": EOF exception found" )
3240 main.log.error( self.name + ": " + self.handle.before )
3241 main.cleanup()
3242 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003243 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003244 main.log.exception( self.name + ": Uncaught exception!" )
3245 main.cleanup()
3246 main.exit()
3247
Jon Hallbd16b922015-03-26 17:53:15 -07003248 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003249 """
3250 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003251 appName is the hierarchical app name, not the feature name
3252 If check is True, method will check the status of the app after the
3253 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003254 Returns main.TRUE if the command was successfully sent
3255 main.FALSE if the cli responded with an error or given
3256 incorrect input
3257 """
3258 try:
3259 if not isinstance( appName, types.StringType ):
3260 main.log.error( self.name + ".deactivateApp(): appName must " +
3261 "be a string" )
3262 return main.FALSE
3263 status = self.appStatus( appName )
3264 if status == "INSTALLED":
3265 return main.TRUE
3266 elif status == "ACTIVE":
3267 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003268 if check and response == main.TRUE:
3269 for i in range(10): # try 10 times then give up
3270 status = self.appStatus( appName )
3271 if status == "INSTALLED":
3272 return main.TRUE
3273 else:
3274 time.sleep( 1 )
3275 return main.FALSE
3276 else: # not check or command didn't succeed
3277 return response
Jon Hall146f1522015-03-24 15:33:24 -07003278 elif status == "UNINSTALLED":
3279 main.log.warn( self.name + ": Tried to deactivate the " +
3280 "application '" + appName + "' which is not " +
3281 "installed." )
3282 return main.TRUE
3283 else:
3284 main.log.error( "Unexpected return value from appStatus: " +
3285 str( status ) )
3286 return main.ERROR
3287 except TypeError:
3288 main.log.exception( self.name + ": Object not as expected" )
3289 return main.ERROR
3290 except pexpect.EOF:
3291 main.log.error( self.name + ": EOF exception found" )
3292 main.log.error( self.name + ": " + self.handle.before )
3293 main.cleanup()
3294 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003295 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003296 main.log.exception( self.name + ": Uncaught exception!" )
3297 main.cleanup()
3298 main.exit()
3299
Jon Hallbd16b922015-03-26 17:53:15 -07003300 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003301 """
3302 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003303 appName is the hierarchical app name, not the feature name
3304 If check is True, method will check the status of the app after the
3305 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003306 Returns main.TRUE if the command was successfully sent
3307 main.FALSE if the cli responded with an error or given
3308 incorrect input
3309 """
3310 # TODO: check with Thomas about the state machine for apps
3311 try:
3312 if not isinstance( appName, types.StringType ):
3313 main.log.error( self.name + ".uninstallApp(): appName must " +
3314 "be a string" )
3315 return main.FALSE
3316 status = self.appStatus( appName )
3317 if status == "INSTALLED":
3318 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003319 if check and response == main.TRUE:
3320 for i in range(10): # try 10 times then give up
3321 status = self.appStatus( appName )
3322 if status == "UNINSTALLED":
3323 return main.TRUE
3324 else:
3325 time.sleep( 1 )
3326 return main.FALSE
3327 else: # not check or command didn't succeed
3328 return response
Jon Hall146f1522015-03-24 15:33:24 -07003329 elif status == "ACTIVE":
3330 main.log.warn( self.name + ": Tried to uninstall the " +
3331 "application '" + appName + "' which is " +
3332 "currently active." )
3333 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003334 if check and response == main.TRUE:
3335 for i in range(10): # try 10 times then give up
3336 status = self.appStatus( appName )
3337 if status == "UNINSTALLED":
3338 return main.TRUE
3339 else:
3340 time.sleep( 1 )
3341 return main.FALSE
3342 else: # not check or command didn't succeed
3343 return response
Jon Hall146f1522015-03-24 15:33:24 -07003344 elif status == "UNINSTALLED":
3345 return main.TRUE
3346 else:
3347 main.log.error( "Unexpected return value from appStatus: " +
3348 str( status ) )
3349 return main.ERROR
3350 except TypeError:
3351 main.log.exception( self.name + ": Object not as expected" )
3352 return main.ERROR
3353 except pexpect.EOF:
3354 main.log.error( self.name + ": EOF exception found" )
3355 main.log.error( self.name + ": " + self.handle.before )
3356 main.cleanup()
3357 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003358 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003359 main.log.exception( self.name + ": Uncaught exception!" )
3360 main.cleanup()
3361 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003362
3363 def appIDs( self, jsonFormat=True ):
3364 """
3365 Show the mappings between app id and app names given by the 'app-ids'
3366 cli command
3367 """
3368 try:
3369 cmdStr = "app-ids"
3370 if jsonFormat:
3371 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003372 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003373 assert "Command not found:" not in output, output
3374 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003375 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003376 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003377 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003378 return None
3379 except TypeError:
3380 main.log.exception( self.name + ": Object not as expected" )
3381 return None
3382 except pexpect.EOF:
3383 main.log.error( self.name + ": EOF exception found" )
3384 main.log.error( self.name + ": " + self.handle.before )
3385 main.cleanup()
3386 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003387 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003388 main.log.exception( self.name + ": Uncaught exception!" )
3389 main.cleanup()
3390 main.exit()
3391
3392 def appToIDCheck( self ):
3393 """
3394 This method will check that each application's ID listed in 'apps' is
3395 the same as the ID listed in 'app-ids'. The check will also check that
3396 there are no duplicate IDs issued. Note that an app ID should be
3397 a globaly unique numerical identifier for app/app-like features. Once
3398 an ID is registered, the ID is never freed up so that if an app is
3399 reinstalled it will have the same ID.
3400
3401 Returns: main.TRUE if the check passes and
3402 main.FALSE if the check fails or
3403 main.ERROR if there is some error in processing the test
3404 """
3405 try:
Jon Hall390696c2015-05-05 17:13:41 -07003406 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003407 rawJson = self.appIDs( jsonFormat=True )
3408 if rawJson:
3409 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003410 else:
Jon Hallc6793552016-01-19 14:18:37 -08003411 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003412 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003413 rawJson = self.apps( jsonFormat=True )
3414 if rawJson:
3415 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003416 else:
Jon Hallc6793552016-01-19 14:18:37 -08003417 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003418 bail = True
3419 if bail:
3420 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003421 result = main.TRUE
3422 for app in apps:
3423 appID = app.get( 'id' )
3424 if appID is None:
3425 main.log.error( "Error parsing app: " + str( app ) )
3426 result = main.FALSE
3427 appName = app.get( 'name' )
3428 if appName is None:
3429 main.log.error( "Error parsing app: " + str( app ) )
3430 result = main.FALSE
3431 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003432 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003433 # main.log.debug( "Comparing " + str( app ) + " to " +
3434 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003435 if not current: # if ids doesn't have this id
3436 result = main.FALSE
3437 main.log.error( "'app-ids' does not have the ID for " +
3438 str( appName ) + " that apps does." )
3439 elif len( current ) > 1:
3440 # there is more than one app with this ID
3441 result = main.FALSE
3442 # We will log this later in the method
3443 elif not current[0][ 'name' ] == appName:
3444 currentName = current[0][ 'name' ]
3445 result = main.FALSE
3446 main.log.error( "'app-ids' has " + str( currentName ) +
3447 " registered under id:" + str( appID ) +
3448 " but 'apps' has " + str( appName ) )
3449 else:
3450 pass # id and name match!
3451 # now make sure that app-ids has no duplicates
3452 idsList = []
3453 namesList = []
3454 for item in ids:
3455 idsList.append( item[ 'id' ] )
3456 namesList.append( item[ 'name' ] )
3457 if len( idsList ) != len( set( idsList ) ) or\
3458 len( namesList ) != len( set( namesList ) ):
3459 main.log.error( "'app-ids' has some duplicate entries: \n"
3460 + json.dumps( ids,
3461 sort_keys=True,
3462 indent=4,
3463 separators=( ',', ': ' ) ) )
3464 result = main.FALSE
3465 return result
Jon Hallc6793552016-01-19 14:18:37 -08003466 except ( TypeError, ValueError ):
3467 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003468 return main.ERROR
3469 except pexpect.EOF:
3470 main.log.error( self.name + ": EOF exception found" )
3471 main.log.error( self.name + ": " + self.handle.before )
3472 main.cleanup()
3473 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003474 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003475 main.log.exception( self.name + ": Uncaught exception!" )
3476 main.cleanup()
3477 main.exit()
3478
Jon Hallfb760a02015-04-13 15:35:03 -07003479 def getCfg( self, component=None, propName=None, short=False,
3480 jsonFormat=True ):
3481 """
3482 Get configuration settings from onos cli
3483 Optional arguments:
3484 component - Optionally only list configurations for a specific
3485 component. If None, all components with configurations
3486 are displayed. Case Sensitive string.
3487 propName - If component is specified, propName option will show
3488 only this specific configuration from that component.
3489 Case Sensitive string.
3490 jsonFormat - Returns output as json. Note that this will override
3491 the short option
3492 short - Short, less verbose, version of configurations.
3493 This is overridden by the json option
3494 returns:
3495 Output from cli as a string or None on error
3496 """
3497 try:
3498 baseStr = "cfg"
3499 cmdStr = " get"
3500 componentStr = ""
3501 if component:
3502 componentStr += " " + component
3503 if propName:
3504 componentStr += " " + propName
3505 if jsonFormat:
3506 baseStr += " -j"
3507 elif short:
3508 baseStr += " -s"
3509 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003510 assert "Command not found:" not in output, output
3511 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003512 return output
3513 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003514 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003515 return None
3516 except TypeError:
3517 main.log.exception( self.name + ": Object not as expected" )
3518 return None
3519 except pexpect.EOF:
3520 main.log.error( self.name + ": EOF exception found" )
3521 main.log.error( self.name + ": " + self.handle.before )
3522 main.cleanup()
3523 main.exit()
3524 except Exception:
3525 main.log.exception( self.name + ": Uncaught exception!" )
3526 main.cleanup()
3527 main.exit()
3528
3529 def setCfg( self, component, propName, value=None, check=True ):
3530 """
3531 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003532 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003533 component - The case sensitive name of the component whose
3534 property is to be set
3535 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003536 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003537 value - The value to set the property to. If None, will unset the
3538 property and revert it to it's default value(if applicable)
3539 check - Boolean, Check whether the option was successfully set this
3540 only applies when a value is given.
3541 returns:
3542 main.TRUE on success or main.FALSE on failure. If check is False,
3543 will return main.TRUE unless there is an error
3544 """
3545 try:
3546 baseStr = "cfg"
3547 cmdStr = " set " + str( component ) + " " + str( propName )
3548 if value is not None:
3549 cmdStr += " " + str( value )
3550 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003551 assert "Command not found:" not in output, output
3552 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003553 if value and check:
3554 results = self.getCfg( component=str( component ),
3555 propName=str( propName ),
3556 jsonFormat=True )
3557 # Check if current value is what we just set
3558 try:
3559 jsonOutput = json.loads( results )
3560 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003561 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003562 main.log.exception( "Error parsing cfg output" )
3563 main.log.error( "output:" + repr( results ) )
3564 return main.FALSE
3565 if current == str( value ):
3566 return main.TRUE
3567 return main.FALSE
3568 return main.TRUE
3569 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003570 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003571 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003572 except ( TypeError, ValueError ):
3573 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003574 return main.FALSE
3575 except pexpect.EOF:
3576 main.log.error( self.name + ": EOF exception found" )
3577 main.log.error( self.name + ": " + self.handle.before )
3578 main.cleanup()
3579 main.exit()
3580 except Exception:
3581 main.log.exception( self.name + ": Uncaught exception!" )
3582 main.cleanup()
3583 main.exit()
3584
Jon Hall390696c2015-05-05 17:13:41 -07003585 def setTestAdd( self, setName, values ):
3586 """
3587 CLI command to add elements to a distributed set.
3588 Arguments:
3589 setName - The name of the set to add to.
3590 values - The value(s) to add to the set, space seperated.
3591 Example usages:
3592 setTestAdd( "set1", "a b c" )
3593 setTestAdd( "set2", "1" )
3594 returns:
3595 main.TRUE on success OR
3596 main.FALSE if elements were already in the set OR
3597 main.ERROR on error
3598 """
3599 try:
3600 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3601 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003602 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003603 try:
3604 # TODO: Maybe make this less hardcoded
3605 # ConsistentMap Exceptions
3606 assert "org.onosproject.store.service" not in output
3607 # Node not leader
3608 assert "java.lang.IllegalStateException" not in output
3609 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003610 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003611 "command: " + str( output ) )
3612 retryTime = 30 # Conservative time, given by Madan
3613 main.log.info( "Waiting " + str( retryTime ) +
3614 "seconds before retrying." )
3615 time.sleep( retryTime ) # Due to change in mastership
3616 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003617 assert "Error executing command" not in output
3618 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3619 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3620 main.log.info( self.name + ": " + output )
3621 if re.search( positiveMatch, output):
3622 return main.TRUE
3623 elif re.search( negativeMatch, output):
3624 return main.FALSE
3625 else:
3626 main.log.error( self.name + ": setTestAdd did not" +
3627 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003628 main.log.debug( self.name + " actual: " + repr( output ) )
3629 return main.ERROR
3630 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003631 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003632 return main.ERROR
3633 except TypeError:
3634 main.log.exception( self.name + ": Object not as expected" )
3635 return main.ERROR
3636 except pexpect.EOF:
3637 main.log.error( self.name + ": EOF exception found" )
3638 main.log.error( self.name + ": " + self.handle.before )
3639 main.cleanup()
3640 main.exit()
3641 except Exception:
3642 main.log.exception( self.name + ": Uncaught exception!" )
3643 main.cleanup()
3644 main.exit()
3645
3646 def setTestRemove( self, setName, values, clear=False, retain=False ):
3647 """
3648 CLI command to remove elements from a distributed set.
3649 Required arguments:
3650 setName - The name of the set to remove from.
3651 values - The value(s) to remove from the set, space seperated.
3652 Optional arguments:
3653 clear - Clear all elements from the set
3654 retain - Retain only the given values. (intersection of the
3655 original set and the given set)
3656 returns:
3657 main.TRUE on success OR
3658 main.FALSE if the set was not changed OR
3659 main.ERROR on error
3660 """
3661 try:
3662 cmdStr = "set-test-remove "
3663 if clear:
3664 cmdStr += "-c " + str( setName )
3665 elif retain:
3666 cmdStr += "-r " + str( setName ) + " " + str( values )
3667 else:
3668 cmdStr += str( setName ) + " " + str( values )
3669 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003670 try:
3671 # TODO: Maybe make this less hardcoded
3672 # ConsistentMap Exceptions
3673 assert "org.onosproject.store.service" not in output
3674 # Node not leader
3675 assert "java.lang.IllegalStateException" not in output
3676 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003677 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003678 "command: " + str( output ) )
3679 retryTime = 30 # Conservative time, given by Madan
3680 main.log.info( "Waiting " + str( retryTime ) +
3681 "seconds before retrying." )
3682 time.sleep( retryTime ) # Due to change in mastership
3683 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003684 assert "Command not found:" not in output, output
3685 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003686 main.log.info( self.name + ": " + output )
3687 if clear:
3688 pattern = "Set " + str( setName ) + " cleared"
3689 if re.search( pattern, output ):
3690 return main.TRUE
3691 elif retain:
3692 positivePattern = str( setName ) + " was pruned to contain " +\
3693 "only elements of set \[(.*)\]"
3694 negativePattern = str( setName ) + " was not changed by " +\
3695 "retaining only elements of the set " +\
3696 "\[(.*)\]"
3697 if re.search( positivePattern, output ):
3698 return main.TRUE
3699 elif re.search( negativePattern, output ):
3700 return main.FALSE
3701 else:
3702 positivePattern = "\[(.*)\] was removed from the set " +\
3703 str( setName )
3704 if ( len( values.split() ) == 1 ):
3705 negativePattern = "\[(.*)\] was not in set " +\
3706 str( setName )
3707 else:
3708 negativePattern = "No element of \[(.*)\] was in set " +\
3709 str( setName )
3710 if re.search( positivePattern, output ):
3711 return main.TRUE
3712 elif re.search( negativePattern, output ):
3713 return main.FALSE
3714 main.log.error( self.name + ": setTestRemove did not" +
3715 " match expected output" )
3716 main.log.debug( self.name + " expected: " + pattern )
3717 main.log.debug( self.name + " actual: " + repr( output ) )
3718 return main.ERROR
3719 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003720 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003721 return main.ERROR
3722 except TypeError:
3723 main.log.exception( self.name + ": Object not as expected" )
3724 return main.ERROR
3725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
3728 main.cleanup()
3729 main.exit()
3730 except Exception:
3731 main.log.exception( self.name + ": Uncaught exception!" )
3732 main.cleanup()
3733 main.exit()
3734
3735 def setTestGet( self, setName, values="" ):
3736 """
3737 CLI command to get the elements in a distributed set.
3738 Required arguments:
3739 setName - The name of the set to remove from.
3740 Optional arguments:
3741 values - The value(s) to check if in the set, space seperated.
3742 returns:
3743 main.ERROR on error OR
3744 A list of elements in the set if no optional arguments are
3745 supplied OR
3746 A tuple containing the list then:
3747 main.FALSE if the given values are not in the set OR
3748 main.TRUE if the given values are in the set OR
3749 """
3750 try:
3751 values = str( values ).strip()
3752 setName = str( setName ).strip()
3753 length = len( values.split() )
3754 containsCheck = None
3755 # Patterns to match
3756 setPattern = "\[(.*)\]"
3757 pattern = "Items in set " + setName + ":\n" + setPattern
3758 containsTrue = "Set " + setName + " contains the value " + values
3759 containsFalse = "Set " + setName + " did not contain the value " +\
3760 values
3761 containsAllTrue = "Set " + setName + " contains the the subset " +\
3762 setPattern
3763 containsAllFalse = "Set " + setName + " did not contain the the" +\
3764 " subset " + setPattern
3765
3766 cmdStr = "set-test-get "
3767 cmdStr += setName + " " + values
3768 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003769 try:
3770 # TODO: Maybe make this less hardcoded
3771 # ConsistentMap Exceptions
3772 assert "org.onosproject.store.service" not in output
3773 # Node not leader
3774 assert "java.lang.IllegalStateException" not in output
3775 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003776 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003777 "command: " + str( output ) )
3778 retryTime = 30 # Conservative time, given by Madan
3779 main.log.info( "Waiting " + str( retryTime ) +
3780 "seconds before retrying." )
3781 time.sleep( retryTime ) # Due to change in mastership
3782 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003783 assert "Command not found:" not in output, output
3784 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003785 main.log.info( self.name + ": " + output )
3786
3787 if length == 0:
3788 match = re.search( pattern, output )
3789 else: # if given values
3790 if length == 1: # Contains output
3791 patternTrue = pattern + "\n" + containsTrue
3792 patternFalse = pattern + "\n" + containsFalse
3793 else: # ContainsAll output
3794 patternTrue = pattern + "\n" + containsAllTrue
3795 patternFalse = pattern + "\n" + containsAllFalse
3796 matchTrue = re.search( patternTrue, output )
3797 matchFalse = re.search( patternFalse, output )
3798 if matchTrue:
3799 containsCheck = main.TRUE
3800 match = matchTrue
3801 elif matchFalse:
3802 containsCheck = main.FALSE
3803 match = matchFalse
3804 else:
3805 main.log.error( self.name + " setTestGet did not match " +\
3806 "expected output" )
3807 main.log.debug( self.name + " expected: " + pattern )
3808 main.log.debug( self.name + " actual: " + repr( output ) )
3809 match = None
3810 if match:
3811 setMatch = match.group( 1 )
3812 if setMatch == '':
3813 setList = []
3814 else:
3815 setList = setMatch.split( ", " )
3816 if length > 0:
3817 return ( setList, containsCheck )
3818 else:
3819 return setList
3820 else: # no match
3821 main.log.error( self.name + ": setTestGet did not" +
3822 " match expected output" )
3823 main.log.debug( self.name + " expected: " + pattern )
3824 main.log.debug( self.name + " actual: " + repr( output ) )
3825 return main.ERROR
3826 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003827 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003828 return main.ERROR
3829 except TypeError:
3830 main.log.exception( self.name + ": Object not as expected" )
3831 return main.ERROR
3832 except pexpect.EOF:
3833 main.log.error( self.name + ": EOF exception found" )
3834 main.log.error( self.name + ": " + self.handle.before )
3835 main.cleanup()
3836 main.exit()
3837 except Exception:
3838 main.log.exception( self.name + ": Uncaught exception!" )
3839 main.cleanup()
3840 main.exit()
3841
3842 def setTestSize( self, setName ):
3843 """
3844 CLI command to get the elements in a distributed set.
3845 Required arguments:
3846 setName - The name of the set to remove from.
3847 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003848 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003849 None on error
3850 """
3851 try:
3852 # TODO: Should this check against the number of elements returned
3853 # and then return true/false based on that?
3854 setName = str( setName ).strip()
3855 # Patterns to match
3856 setPattern = "\[(.*)\]"
3857 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3858 setPattern
3859 cmdStr = "set-test-get -s "
3860 cmdStr += setName
3861 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003862 try:
3863 # TODO: Maybe make this less hardcoded
3864 # ConsistentMap Exceptions
3865 assert "org.onosproject.store.service" not in output
3866 # Node not leader
3867 assert "java.lang.IllegalStateException" not in output
3868 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003869 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003870 "command: " + str( output ) )
3871 retryTime = 30 # Conservative time, given by Madan
3872 main.log.info( "Waiting " + str( retryTime ) +
3873 "seconds before retrying." )
3874 time.sleep( retryTime ) # Due to change in mastership
3875 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003876 assert "Command not found:" not in output, output
3877 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003878 main.log.info( self.name + ": " + output )
3879 match = re.search( pattern, output )
3880 if match:
3881 setSize = int( match.group( 1 ) )
3882 setMatch = match.group( 2 )
3883 if len( setMatch.split() ) == setSize:
3884 main.log.info( "The size returned by " + self.name +
3885 " matches the number of elements in " +
3886 "the returned set" )
3887 else:
3888 main.log.error( "The size returned by " + self.name +
3889 " does not match the number of " +
3890 "elements in the returned set." )
3891 return setSize
3892 else: # no match
3893 main.log.error( self.name + ": setTestGet did not" +
3894 " match expected output" )
3895 main.log.debug( self.name + " expected: " + pattern )
3896 main.log.debug( self.name + " actual: " + repr( output ) )
3897 return None
3898 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003899 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003900 return None
Jon Hall390696c2015-05-05 17:13:41 -07003901 except TypeError:
3902 main.log.exception( self.name + ": Object not as expected" )
3903 return None
3904 except pexpect.EOF:
3905 main.log.error( self.name + ": EOF exception found" )
3906 main.log.error( self.name + ": " + self.handle.before )
3907 main.cleanup()
3908 main.exit()
3909 except Exception:
3910 main.log.exception( self.name + ": Uncaught exception!" )
3911 main.cleanup()
3912 main.exit()
3913
Jon Hall80daded2015-05-27 16:07:00 -07003914 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003915 """
3916 Command to list the various counters in the system.
3917 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003918 if jsonFormat, a string of the json object returned by the cli
3919 command
3920 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003921 None on error
3922 """
Jon Hall390696c2015-05-05 17:13:41 -07003923 try:
3924 counters = {}
3925 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003926 if jsonFormat:
3927 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003928 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003929 assert "Command not found:" not in output, output
3930 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003931 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003932 return output
Jon Hall390696c2015-05-05 17:13:41 -07003933 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003934 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003935 return None
Jon Hall390696c2015-05-05 17:13:41 -07003936 except TypeError:
3937 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003938 return None
Jon Hall390696c2015-05-05 17:13:41 -07003939 except pexpect.EOF:
3940 main.log.error( self.name + ": EOF exception found" )
3941 main.log.error( self.name + ": " + self.handle.before )
3942 main.cleanup()
3943 main.exit()
3944 except Exception:
3945 main.log.exception( self.name + ": Uncaught exception!" )
3946 main.cleanup()
3947 main.exit()
3948
Jon Halle1a3b752015-07-22 13:02:46 -07003949 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003950 """
Jon Halle1a3b752015-07-22 13:02:46 -07003951 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003952 Required arguments:
3953 counter - The name of the counter to increment.
3954 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003955 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003956 inMemory - use in memory map for the counter
3957 returns:
3958 integer value of the counter or
3959 None on Error
3960 """
3961 try:
3962 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003963 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003964 cmdStr = "counter-test-increment "
3965 if inMemory:
3966 cmdStr += "-i "
3967 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003968 if delta != 1:
3969 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003970 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003971 try:
3972 # TODO: Maybe make this less hardcoded
3973 # ConsistentMap Exceptions
3974 assert "org.onosproject.store.service" not in output
3975 # Node not leader
3976 assert "java.lang.IllegalStateException" not in output
3977 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003978 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003979 "command: " + str( output ) )
3980 retryTime = 30 # Conservative time, given by Madan
3981 main.log.info( "Waiting " + str( retryTime ) +
3982 "seconds before retrying." )
3983 time.sleep( retryTime ) # Due to change in mastership
3984 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003985 assert "Command not found:" not in output, output
3986 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003987 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003988 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003989 match = re.search( pattern, output )
3990 if match:
3991 return int( match.group( 1 ) )
3992 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003993 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003994 " match expected output." )
3995 main.log.debug( self.name + " expected: " + pattern )
3996 main.log.debug( self.name + " actual: " + repr( output ) )
3997 return None
3998 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003999 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004000 return None
4001 except TypeError:
4002 main.log.exception( self.name + ": Object not as expected" )
4003 return None
4004 except pexpect.EOF:
4005 main.log.error( self.name + ": EOF exception found" )
4006 main.log.error( self.name + ": " + self.handle.before )
4007 main.cleanup()
4008 main.exit()
4009 except Exception:
4010 main.log.exception( self.name + ": Uncaught exception!" )
4011 main.cleanup()
4012 main.exit()
4013
Jon Halle1a3b752015-07-22 13:02:46 -07004014 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4015 """
4016 CLI command to get a distributed counter then add a delta to it.
4017 Required arguments:
4018 counter - The name of the counter to increment.
4019 Optional arguments:
4020 delta - The long to add to the counter
4021 inMemory - use in memory map for the counter
4022 returns:
4023 integer value of the counter or
4024 None on Error
4025 """
4026 try:
4027 counter = str( counter )
4028 delta = int( delta )
4029 cmdStr = "counter-test-increment -g "
4030 if inMemory:
4031 cmdStr += "-i "
4032 cmdStr += counter
4033 if delta != 1:
4034 cmdStr += " " + str( delta )
4035 output = self.sendline( cmdStr )
4036 try:
4037 # TODO: Maybe make this less hardcoded
4038 # ConsistentMap Exceptions
4039 assert "org.onosproject.store.service" not in output
4040 # Node not leader
4041 assert "java.lang.IllegalStateException" not in output
4042 except AssertionError:
4043 main.log.error( "Error in processing '" + cmdStr + "' " +
4044 "command: " + str( output ) )
4045 retryTime = 30 # Conservative time, given by Madan
4046 main.log.info( "Waiting " + str( retryTime ) +
4047 "seconds before retrying." )
4048 time.sleep( retryTime ) # Due to change in mastership
4049 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004050 assert "Command not found:" not in output, output
4051 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004052 main.log.info( self.name + ": " + output )
4053 pattern = counter + " was updated to (-?\d+)"
4054 match = re.search( pattern, output )
4055 if match:
4056 return int( match.group( 1 ) )
4057 else:
4058 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4059 " match expected output." )
4060 main.log.debug( self.name + " expected: " + pattern )
4061 main.log.debug( self.name + " actual: " + repr( output ) )
4062 return None
4063 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004064 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004065 return None
4066 except TypeError:
4067 main.log.exception( self.name + ": Object not as expected" )
4068 return None
4069 except pexpect.EOF:
4070 main.log.error( self.name + ": EOF exception found" )
4071 main.log.error( self.name + ": " + self.handle.before )
4072 main.cleanup()
4073 main.exit()
4074 except Exception:
4075 main.log.exception( self.name + ": Uncaught exception!" )
4076 main.cleanup()
4077 main.exit()
4078
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004079 def summary( self, jsonFormat=True ):
4080 """
4081 Description: Execute summary command in onos
4082 Returns: json object ( summary -j ), returns main.FALSE if there is
4083 no output
4084
4085 """
4086 try:
4087 cmdStr = "summary"
4088 if jsonFormat:
4089 cmdStr += " -j"
4090 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004091 assert "Command not found:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004092 if re.search( "Error:", handle ):
4093 main.log.error( self.name + ": summary() response: " +
4094 str( handle ) )
4095 if not handle:
4096 main.log.error( self.name + ": There is no output in " +
4097 "summary command" )
4098 return main.FALSE
4099 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004100 except AssertionError:
4101 main.log.exception( "" )
4102 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004103 except TypeError:
4104 main.log.exception( self.name + ": Object not as expected" )
4105 return None
4106 except pexpect.EOF:
4107 main.log.error( self.name + ": EOF exception found" )
4108 main.log.error( self.name + ": " + self.handle.before )
4109 main.cleanup()
4110 main.exit()
4111 except Exception:
4112 main.log.exception( self.name + ": Uncaught exception!" )
4113 main.cleanup()
4114 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004115
4116 def transactionalMapGet( self, keyName, inMemory=False ):
4117 """
4118 CLI command to get the value of a key in a consistent map using
4119 transactions. This a test function and can only get keys from the
4120 test map hard coded into the cli command
4121 Required arguments:
4122 keyName - The name of the key to get
4123 Optional arguments:
4124 inMemory - use in memory map for the counter
4125 returns:
4126 The string value of the key or
4127 None on Error
4128 """
4129 try:
4130 keyName = str( keyName )
4131 cmdStr = "transactional-map-test-get "
4132 if inMemory:
4133 cmdStr += "-i "
4134 cmdStr += keyName
4135 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004136 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004137 try:
4138 # TODO: Maybe make this less hardcoded
4139 # ConsistentMap Exceptions
4140 assert "org.onosproject.store.service" not in output
4141 # Node not leader
4142 assert "java.lang.IllegalStateException" not in output
4143 except AssertionError:
4144 main.log.error( "Error in processing '" + cmdStr + "' " +
4145 "command: " + str( output ) )
4146 return None
4147 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4148 if "Key " + keyName + " not found." in output:
4149 return None
4150 else:
4151 match = re.search( pattern, output )
4152 if match:
4153 return match.groupdict()[ 'value' ]
4154 else:
4155 main.log.error( self.name + ": transactionlMapGet did not" +
4156 " match expected output." )
4157 main.log.debug( self.name + " expected: " + pattern )
4158 main.log.debug( self.name + " actual: " + repr( output ) )
4159 return None
Jon Hallc6793552016-01-19 14:18:37 -08004160 except AssertionError:
4161 main.log.exception( "" )
4162 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004163 except TypeError:
4164 main.log.exception( self.name + ": Object not as expected" )
4165 return None
4166 except pexpect.EOF:
4167 main.log.error( self.name + ": EOF exception found" )
4168 main.log.error( self.name + ": " + self.handle.before )
4169 main.cleanup()
4170 main.exit()
4171 except Exception:
4172 main.log.exception( self.name + ": Uncaught exception!" )
4173 main.cleanup()
4174 main.exit()
4175
4176 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4177 """
4178 CLI command to put a value into 'numKeys' number of keys in a
4179 consistent map using transactions. This a test function and can only
4180 put into keys named 'Key#' of the test map hard coded into the cli command
4181 Required arguments:
4182 numKeys - Number of keys to add the value to
4183 value - The string value to put into the keys
4184 Optional arguments:
4185 inMemory - use in memory map for the counter
4186 returns:
4187 A dictionary whose keys are the name of the keys put into the map
4188 and the values of the keys are dictionaries whose key-values are
4189 'value': value put into map and optionaly
4190 'oldValue': Previous value in the key or
4191 None on Error
4192
4193 Example output
4194 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4195 'Key2': {'value': 'Testing'} }
4196 """
4197 try:
4198 numKeys = str( numKeys )
4199 value = str( value )
4200 cmdStr = "transactional-map-test-put "
4201 if inMemory:
4202 cmdStr += "-i "
4203 cmdStr += numKeys + " " + value
4204 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004205 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004206 try:
4207 # TODO: Maybe make this less hardcoded
4208 # ConsistentMap Exceptions
4209 assert "org.onosproject.store.service" not in output
4210 # Node not leader
4211 assert "java.lang.IllegalStateException" not in output
4212 except AssertionError:
4213 main.log.error( "Error in processing '" + cmdStr + "' " +
4214 "command: " + str( output ) )
4215 return None
4216 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4217 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4218 results = {}
4219 for line in output.splitlines():
4220 new = re.search( newPattern, line )
4221 updated = re.search( updatedPattern, line )
4222 if new:
4223 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4224 elif updated:
4225 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004226 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004227 else:
4228 main.log.error( self.name + ": transactionlMapGet did not" +
4229 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004230 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4231 newPattern,
4232 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004233 main.log.debug( self.name + " actual: " + repr( output ) )
4234 return results
Jon Hallc6793552016-01-19 14:18:37 -08004235 except AssertionError:
4236 main.log.exception( "" )
4237 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004238 except TypeError:
4239 main.log.exception( self.name + ": Object not as expected" )
4240 return None
4241 except pexpect.EOF:
4242 main.log.error( self.name + ": EOF exception found" )
4243 main.log.error( self.name + ": " + self.handle.before )
4244 main.cleanup()
4245 main.exit()
4246 except Exception:
4247 main.log.exception( self.name + ": Uncaught exception!" )
4248 main.cleanup()
4249 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004250
acsmarsdaea66c2015-09-03 11:44:06 -07004251 def maps( self, jsonFormat=True ):
4252 """
4253 Description: Returns result of onos:maps
4254 Optional:
4255 * jsonFormat: enable json formatting of output
4256 """
4257 try:
4258 cmdStr = "maps"
4259 if jsonFormat:
4260 cmdStr += " -j"
4261 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004262 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004263 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004264 except AssertionError:
4265 main.log.exception( "" )
4266 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004267 except TypeError:
4268 main.log.exception( self.name + ": Object not as expected" )
4269 return None
4270 except pexpect.EOF:
4271 main.log.error( self.name + ": EOF exception found" )
4272 main.log.error( self.name + ": " + self.handle.before )
4273 main.cleanup()
4274 main.exit()
4275 except Exception:
4276 main.log.exception( self.name + ": Uncaught exception!" )
4277 main.cleanup()
4278 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004279
4280 def getSwController( self, uri, jsonFormat=True ):
4281 """
4282 Descrition: Gets the controller information from the device
4283 """
4284 try:
4285 cmd = "device-controllers "
4286 if jsonFormat:
4287 cmd += "-j "
4288 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004289 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004290 return response
Jon Hallc6793552016-01-19 14:18:37 -08004291 except AssertionError:
4292 main.log.exception( "" )
4293 return None
GlennRC050596c2015-11-18 17:06:41 -08004294 except TypeError:
4295 main.log.exception( self.name + ": Object not as expected" )
4296 return None
4297 except pexpect.EOF:
4298 main.log.error( self.name + ": EOF exception found" )
4299 main.log.error( self.name + ": " + self.handle.before )
4300 main.cleanup()
4301 main.exit()
4302 except Exception:
4303 main.log.exception( self.name + ": Uncaught exception!" )
4304 main.cleanup()
4305 main.exit()
4306
4307 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4308 """
4309 Descrition: sets the controller(s) for the specified device
4310
4311 Parameters:
4312 Required: uri - String: The uri of the device(switch).
4313 ip - String or List: The ip address of the controller.
4314 This parameter can be formed in a couple of different ways.
4315 VALID:
4316 10.0.0.1 - just the ip address
4317 tcp:10.0.0.1 - the protocol and the ip address
4318 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4319 so that you can add controllers with different
4320 protocols and ports
4321 INVALID:
4322 10.0.0.1:6653 - this is not supported by ONOS
4323
4324 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4325 port - The port number.
4326 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4327
4328 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4329 """
4330 try:
4331 cmd = "device-setcontrollers"
4332
4333 if jsonFormat:
4334 cmd += " -j"
4335 cmd += " " + uri
4336 if isinstance( ip, str ):
4337 ip = [ip]
4338 for item in ip:
4339 if ":" in item:
4340 sitem = item.split( ":" )
4341 if len(sitem) == 3:
4342 cmd += " " + item
4343 elif "." in sitem[1]:
4344 cmd += " {}:{}".format(item, port)
4345 else:
4346 main.log.error( "Malformed entry: " + item )
4347 raise TypeError
4348 else:
4349 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004350 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004351 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004352 if "Error" in response:
4353 main.log.error( response )
4354 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004355 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004356 except AssertionError:
4357 main.log.exception( "" )
4358 return None
GlennRC050596c2015-11-18 17:06:41 -08004359 except TypeError:
4360 main.log.exception( self.name + ": Object not as expected" )
4361 return main.FALSE
4362 except pexpect.EOF:
4363 main.log.error( self.name + ": EOF exception found" )
4364 main.log.error( self.name + ": " + self.handle.before )
4365 main.cleanup()
4366 main.exit()
4367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
4369 main.cleanup()
4370 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004371
4372 def removeDevice( self, device ):
4373 '''
4374 Description:
4375 Remove a device from ONOS by passing the uri of the device(s).
4376 Parameters:
4377 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4378 Returns:
4379 Returns main.FALSE if an exception is thrown or an error is present
4380 in the response. Otherwise, returns main.TRUE.
4381 NOTE:
4382 If a host cannot be removed, then this function will return main.FALSE
4383 '''
4384 try:
4385 if type( device ) is str:
4386 device = list( device )
4387
4388 for d in device:
4389 time.sleep( 1 )
4390 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004391 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004392 if "Error" in response:
4393 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4394 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004395 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004396 except AssertionError:
4397 main.log.exception( "" )
4398 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004399 except TypeError:
4400 main.log.exception( self.name + ": Object not as expected" )
4401 return main.FALSE
4402 except pexpect.EOF:
4403 main.log.error( self.name + ": EOF exception found" )
4404 main.log.error( self.name + ": " + self.handle.before )
4405 main.cleanup()
4406 main.exit()
4407 except Exception:
4408 main.log.exception( self.name + ": Uncaught exception!" )
4409 main.cleanup()
4410 main.exit()
4411
4412 def removeHost( self, host ):
4413 '''
4414 Description:
4415 Remove a host from ONOS by passing the id of the host(s)
4416 Parameters:
4417 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4418 Returns:
4419 Returns main.FALSE if an exception is thrown or an error is present
4420 in the response. Otherwise, returns main.TRUE.
4421 NOTE:
4422 If a host cannot be removed, then this function will return main.FALSE
4423 '''
4424 try:
4425 if type( host ) is str:
4426 host = list( host )
4427
4428 for h in host:
4429 time.sleep( 1 )
4430 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004431 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004432 if "Error" in response:
4433 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4434 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004435 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004436 except AssertionError:
4437 main.log.exception( "" )
4438 return None
GlennRC20fc6522015-12-23 23:26:57 -08004439 except TypeError:
4440 main.log.exception( self.name + ": Object not as expected" )
4441 return main.FALSE
4442 except pexpect.EOF:
4443 main.log.error( self.name + ": EOF exception found" )
4444 main.log.error( self.name + ": " + self.handle.before )
4445 main.cleanup()
4446 main.exit()
4447 except Exception:
4448 main.log.exception( self.name + ": Uncaught exception!" )
4449 main.cleanup()
4450 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004451
Jon Hallc6793552016-01-19 14:18:37 -08004452 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004453 '''
4454 Description:
4455 Bring link down or up in the null-provider.
4456 params:
4457 begin - (string) One end of a device or switch.
4458 end - (string) the other end of the device or switch
4459 returns:
4460 main.TRUE if no exceptions were thrown and no Errors are
4461 present in the resoponse. Otherwise, returns main.FALSE
4462 '''
4463 try:
Jon Hallc6793552016-01-19 14:18:37 -08004464 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004465 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004466 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004467 if "Error" in response or "Failure" in response:
4468 main.log.error( response )
4469 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004470 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004471 except AssertionError:
4472 main.log.exception( "" )
4473 return None
GlennRCed771242016-01-13 17:02:47 -08004474 except TypeError:
4475 main.log.exception( self.name + ": Object not as expected" )
4476 return main.FALSE
4477 except pexpect.EOF:
4478 main.log.error( self.name + ": EOF exception found" )
4479 main.log.error( self.name + ": " + self.handle.before )
4480 main.cleanup()
4481 main.exit()
4482 except Exception:
4483 main.log.exception( self.name + ": Uncaught exception!" )
4484 main.cleanup()
4485 main.exit()
4486