blob: bb57b9ebfe85494377ed9736c2520a2406ce99e0 [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:
62 if os.getenv( str( self.ip_address ) ) != None:
63 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="",
212 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 """
andrewonlab95ce8322014-10-13 14:12:04 -0400227 try:
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.sendline( "" )
229 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700230 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500231
232 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500234 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400235
kelvin8ec71442015-01-15 16:57:00 -0800236 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800238 i = self.handle.expect( [
239 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700240 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400241
242 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800244 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800246 "config:property-set -p org.apache.karaf.shell\
247 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800248 karafTimeout )
249 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800251 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400252 return main.TRUE
253 else:
kelvin8ec71442015-01-15 16:57:00 -0800254 # If failed, send ctrl+c to process and try again
255 main.log.info( "Starting CLI failed. Retrying..." )
256 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800258 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
259 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400260 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800262 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800263 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800264 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 "config:property-set -p org.apache.karaf.shell\
266 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800267 karafTimeout )
268 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800270 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400271 return main.TRUE
272 else:
kelvin8ec71442015-01-15 16:57:00 -0800273 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400275 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400276
Jon Halld4d4b372015-01-28 16:02:41 -0800277 except TypeError:
278 main.log.exception( self.name + ": Object not as expected" )
279 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400280 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800281 main.log.error( self.name + ": EOF exception found" )
282 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400283 main.cleanup()
284 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800285 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800286 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400287 main.cleanup()
288 main.exit()
289
Jon Hallefbd9792015-03-05 16:11:36 -0800290 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800291 """
292 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800293 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800294 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800295 Available level: DEBUG, TRACE, INFO, WARN, ERROR
296 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800297 """
298 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800299 lvlStr = ""
300 if level:
301 lvlStr = "--level=" + level
302
kelvin-onlab9f541032015-02-04 16:19:53 -0800303 self.handle.sendline( "" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700304 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700305 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700306 main.log.error( self.name + ": onos cli session closed." )
307 main.cleanup()
308 main.exit()
309 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700310 self.handle.sendline( "" )
311 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800312 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700313 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800314 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800315
kelvin-onlab9f541032015-02-04 16:19:53 -0800316 response = self.handle.before
317 if re.search( "Error", response ):
318 return main.FALSE
319 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700320 except pexpect.TIMEOUT:
321 main.log.exception( self.name + ": TIMEOUT exception found" )
322 main.cleanup()
323 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800324 except pexpect.EOF:
325 main.log.error( self.name + ": EOF exception found" )
326 main.log.error( self.name + ": " + self.handle.before )
327 main.cleanup()
328 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800329 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800330 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400331 main.cleanup()
332 main.exit()
333
Jon Hallc6358dd2015-04-10 12:44:28 -0700334 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800335 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800336 Send a completely user specified string to
337 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400338 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800339
andrewonlaba18f6bf2014-10-13 19:31:54 -0400340 Warning: There are no sanity checking to commands
341 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800342 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400343 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800344 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
345 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800346 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800347 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
348 response = self.handle.before
349 if i == 2:
350 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700351 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800352 response += self.handle.before
353 print response
354 try:
355 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700356 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800357 pass
358 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800359 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800360 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700361 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700362 main.log.debug( self.name + ": Raw output" )
363 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700364
365 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800366 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800367 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700368 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700369 main.log.debug( self.name + ": ansiEscape output" )
370 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700371
kelvin-onlabfb521662015-02-27 09:52:40 -0800372 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800373 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700374 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700375 main.log.debug( self.name + ": Removed extra returns " +
376 "from output" )
377 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700378
379 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800380 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700381 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.log.debug( self.name + ": parsed and stripped output" )
383 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700384
Jon Hall63604932015-02-26 17:09:50 -0800385 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700386 output = response.split( cmdStr.strip(), 1 )
387 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700388 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700389 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700390 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700391 return output[1].strip()
392 except IndexError:
393 main.log.exception( self.name + ": Object not as expected" )
394 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800395 except TypeError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400398 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800399 main.log.error( self.name + ": EOF exception found" )
400 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400401 main.cleanup()
402 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800403 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800404 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400405 main.cleanup()
406 main.exit()
407
kelvin8ec71442015-01-15 16:57:00 -0800408 # IMPORTANT NOTE:
409 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800410 # the cli command changing 'a:b' with 'aB'.
411 # Ex ) onos:topology > onosTopology
412 # onos:links > onosLinks
413 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800414
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800416 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417 Adds a new cluster node by ID and address information.
418 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800419 * nodeId
420 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400424 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 cmdStr = "add-node " + str( nodeId ) + " " +\
426 str( ONOSIp ) + " " + str( tcpPort )
427 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800428 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800429 main.log.error( "Error in adding node" )
430 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800431 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400434 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800435 except TypeError:
436 main.log.exception( self.name + ": Object not as expected" )
437 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800439 main.log.error( self.name + ": EOF exception found" )
440 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 main.cleanup()
442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800444 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 main.cleanup()
446 main.exit()
447
kelvin-onlabd3b64892015-01-20 13:26:24 -0800448 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800449 """
andrewonlab86dc3082014-10-13 18:18:38 -0400450 Removes a cluster by ID
451 Issues command: 'remove-node [<node-id>]'
452 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800453 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800454 """
andrewonlab86dc3082014-10-13 18:18:38 -0400455 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400456
kelvin-onlabd3b64892015-01-20 13:26:24 -0800457 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700458 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700459 if re.search( "Error", handle ):
460 main.log.error( "Error in removing node" )
461 main.log.error( handle )
462 return main.FALSE
463 else:
464 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800465 except TypeError:
466 main.log.exception( self.name + ": Object not as expected" )
467 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400468 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800469 main.log.error( self.name + ": EOF exception found" )
470 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400471 main.cleanup()
472 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800473 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800474 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400475 main.cleanup()
476 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400477
Jon Hall61282e32015-03-19 11:34:11 -0700478 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800479 """
andrewonlab7c211572014-10-15 16:45:20 -0400480 List the nodes currently visible
481 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700482 Optional argument:
483 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800484 """
andrewonlab7c211572014-10-15 16:45:20 -0400485 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700486 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700487 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 cmdStr += " -j"
489 output = self.sendline( cmdStr )
490 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800491 except TypeError:
492 main.log.exception( self.name + ": Object not as expected" )
493 return None
andrewonlab7c211572014-10-15 16:45:20 -0400494 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800495 main.log.error( self.name + ": EOF exception found" )
496 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400497 main.cleanup()
498 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800499 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800500 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400501 main.cleanup()
502 main.exit()
503
kelvin8ec71442015-01-15 16:57:00 -0800504 def topology( self ):
505 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700506 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700507 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700508 Return:
509 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800510 """
andrewonlab95ce8322014-10-13 14:12:04 -0400511 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700512 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800513 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400515 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800516 except TypeError:
517 main.log.exception( self.name + ": Object not as expected" )
518 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400519 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800520 main.log.error( self.name + ": EOF exception found" )
521 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400522 main.cleanup()
523 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800524 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800525 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400526 main.cleanup()
527 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800528
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800530 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700531 Installs a specified feature by issuing command:
532 'feature:install <feature_str>'
533 NOTE: This is now deprecated, you should use the activateApp method
534 instead
kelvin8ec71442015-01-15 16:57:00 -0800535 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400536 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800537 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538 handle = self.sendline( cmdStr )
539 if re.search( "Error", handle ):
540 main.log.error( "Error in installing feature" )
541 main.log.error( handle )
542 return main.FALSE
543 else:
544 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800545 except TypeError:
546 main.log.exception( self.name + ": Object not as expected" )
547 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400548 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800549 main.log.error( self.name + ": EOF exception found" )
550 main.log.error( self.name + ": " + self.handle.before )
551 main.log.report( "Failed to install feature" )
552 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400553 main.cleanup()
554 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800555 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800556 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800557 main.log.report( "Failed to install feature" )
558 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 main.cleanup()
560 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800561
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800563 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700564 Uninstalls a specified feature by issuing command:
565 'feature:uninstall <feature_str>'
566 NOTE: This is now deprecated, you should use the deactivateApp method
567 instead
kelvin8ec71442015-01-15 16:57:00 -0800568 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800570 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
571 handle = self.sendline( cmdStr )
572 if handle != '':
573 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700574 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800575 # TODO: Check for possible error responses from karaf
576 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800577 main.log.info( "Feature needs to be installed before " +
578 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700579 return main.TRUE
580 if re.search( "Error", output ):
581 main.log.error( "Error in uninstalling feature" )
582 main.log.error( output )
583 return main.FALSE
584 else:
585 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800586 except TypeError:
587 main.log.exception( self.name + ": Object not as expected" )
588 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400589 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800590 main.log.error( self.name + ": EOF exception found" )
591 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 main.cleanup()
593 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800594 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800595 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400596 main.cleanup()
597 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800598
jenkins7ead5a82015-03-13 10:28:21 -0700599 def deviceRemove( self, deviceId ):
600 """
601 Removes particular device from storage
602
603 TODO: refactor this function
604 """
605 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700606 cmdStr = "device-remove " + str( deviceId )
607 handle = self.sendline( cmdStr )
608 if re.search( "Error", handle ):
609 main.log.error( "Error in removing device" )
610 main.log.error( handle )
611 return main.FALSE
612 else:
613 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700614 except TypeError:
615 main.log.exception( self.name + ": Object not as expected" )
616 return None
617 except pexpect.EOF:
618 main.log.error( self.name + ": EOF exception found" )
619 main.log.error( self.name + ": " + self.handle.before )
620 main.cleanup()
621 main.exit()
622 except Exception:
623 main.log.exception( self.name + ": Uncaught exception!" )
624 main.cleanup()
625 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800628 """
Jon Hall7b02d952014-10-17 20:14:54 -0400629 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400630 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800632 """
andrewonlab86dc3082014-10-13 18:18:38 -0400633 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 cmdStr += " -j"
637 handle = self.sendline( cmdStr )
638 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlab7c211572014-10-15 16:45:20 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400645 main.cleanup()
646 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400649 main.cleanup()
650 main.exit()
651
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800653 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800654 This balances the devices across all controllers
655 by issuing command: 'onos> onos:balance-masters'
656 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800657 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800658 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 handle = self.sendline( cmdStr )
661 if re.search( "Error", handle ):
662 main.log.error( "Error in balancing masters" )
663 main.log.error( handle )
664 return main.FALSE
665 else:
666 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800667 except TypeError:
668 main.log.exception( self.name + ": Object not as expected" )
669 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800670 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800671 main.log.error( self.name + ": EOF exception found" )
672 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800673 main.cleanup()
674 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800677 main.cleanup()
678 main.exit()
679
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800681 """
Jon Halle8217482014-10-17 13:49:14 -0400682 Lists all core links
683 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800685 """
Jon Halle8217482014-10-17 13:49:14 -0400686 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700687 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700689 cmdStr += " -j"
690 handle = self.sendline( cmdStr )
691 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800692 except TypeError:
693 main.log.exception( self.name + ": Object not as expected" )
694 return None
Jon Halle8217482014-10-17 13:49:14 -0400695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800696 main.log.error( self.name + ": EOF exception found" )
697 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400698 main.cleanup()
699 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800700 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800701 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400702 main.cleanup()
703 main.exit()
704
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800706 """
Jon Halle8217482014-10-17 13:49:14 -0400707 Lists all ports
708 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800710 """
Jon Halle8217482014-10-17 13:49:14 -0400711 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700712 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr += " -j"
715 handle = self.sendline( cmdStr )
716 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800717 except TypeError:
718 main.log.exception( self.name + ": Object not as expected" )
719 return None
Jon Halle8217482014-10-17 13:49:14 -0400720 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800721 main.log.error( self.name + ": EOF exception found" )
722 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400723 main.cleanup()
724 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800725 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800726 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400727 main.cleanup()
728 main.exit()
729
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800731 """
Jon Hall983a1702014-10-28 18:44:22 -0400732 Lists all devices and the controllers with roles assigned to them
733 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800735 """
andrewonlab7c211572014-10-15 16:45:20 -0400736 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700737 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 cmdStr += " -j"
740 handle = self.sendline( cmdStr )
741 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800742 except TypeError:
743 main.log.exception( self.name + ": Object not as expected" )
744 return None
Jon Hall983a1702014-10-28 18:44:22 -0400745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800746 main.log.error( self.name + ": EOF exception found" )
747 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400748 main.cleanup()
749 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800750 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800751 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400752 main.cleanup()
753 main.exit()
754
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800756 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800757 Given the a string containing the json representation of the "roles"
758 cli command and a partial or whole device id, returns a json object
759 containing the roles output for the first device whose id contains
760 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400761
762 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800763 A dict of the role assignments for the given device or
764 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall983a1702014-10-28 18:44:22 -0400766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400768 return None
769 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 rawRoles = self.roles()
771 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800772 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800774 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400776 return device
777 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800778 except TypeError:
779 main.log.exception( self.name + ": Object not as expected" )
780 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400784 main.cleanup()
785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800786 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800787 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400788 main.cleanup()
789 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800790
kelvin-onlabd3b64892015-01-20 13:26:24 -0800791 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800792 """
Jon Hall94fd0472014-12-08 11:52:42 -0800793 Iterates through each device and checks if there is a master assigned
794 Returns: main.TRUE if each device has a master
795 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800796 """
Jon Hall94fd0472014-12-08 11:52:42 -0800797 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 rawRoles = self.roles()
799 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800800 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800802 # print device
803 if device[ 'master' ] == "none":
804 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800805 return main.FALSE
806 return main.TRUE
807
Jon Halld4d4b372015-01-28 16:02:41 -0800808 except TypeError:
809 main.log.exception( self.name + ": Object not as expected" )
810 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800811 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800812 main.log.error( self.name + ": EOF exception found" )
813 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800814 main.cleanup()
815 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800816 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800817 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800818 main.cleanup()
819 main.exit()
820
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800822 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400823 Returns string of paths, and the cost.
824 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800825 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400826 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800827 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
828 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800829 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800830 main.log.error( "Error in getting paths" )
831 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400832 else:
kelvin8ec71442015-01-15 16:57:00 -0800833 path = handle.split( ";" )[ 0 ]
834 cost = handle.split( ";" )[ 1 ]
835 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800836 except TypeError:
837 main.log.exception( self.name + ": Object not as expected" )
838 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400839 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800840 main.log.error( self.name + ": EOF exception found" )
841 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400842 main.cleanup()
843 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800844 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800845 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400846 main.cleanup()
847 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800848
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800850 """
Jon Hallffb386d2014-11-21 13:43:38 -0800851 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400852 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800854 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400855 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700856 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700858 cmdStr += " -j"
859 handle = self.sendline( cmdStr )
860 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800861 except TypeError:
862 main.log.exception( self.name + ": Object not as expected" )
863 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400864 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800865 main.log.error( self.name + ": EOF exception found" )
866 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400867 main.cleanup()
868 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800869 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800870 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400871 main.cleanup()
872 main.exit()
873
kelvin-onlabd3b64892015-01-20 13:26:24 -0800874 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800875 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400876 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800877
Jon Hallefbd9792015-03-05 16:11:36 -0800878 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800879 partial mac address
880
Jon Hall42db6dc2014-10-24 19:03:48 -0400881 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800882 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400883 try:
kelvin8ec71442015-01-15 16:57:00 -0800884 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400885 return None
886 else:
887 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 rawHosts = self.hosts()
889 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800890 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800892 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800893 if not host:
894 pass
895 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400896 return host
897 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800898 except TypeError:
899 main.log.exception( self.name + ": Object not as expected" )
900 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400901 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800902 main.log.error( self.name + ": EOF exception found" )
903 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400904 main.cleanup()
905 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800906 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800907 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400908 main.cleanup()
909 main.exit()
910
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800912 """
913 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400914 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800915
andrewonlab3f0a4af2014-10-17 12:25:14 -0400916 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400918 IMPORTANT:
919 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800920 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400921 Furthermore, it assumes that value of VLAN is '-1'
922 Description:
kelvin8ec71442015-01-15 16:57:00 -0800923 Converts mininet hosts ( h1, h2, h3... ) into
924 ONOS format ( 00:00:00:00:00:01/-1 , ... )
925 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400926 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800930 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 hostHex = hex( int( host ) ).zfill( 12 )
932 hostHex = str( hostHex ).replace( 'x', '0' )
933 i = iter( str( hostHex ) )
934 hostHex = ":".join( a + b for a, b in zip( i, i ) )
935 hostHex = hostHex + "/-1"
936 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400937
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400939
Jon Halld4d4b372015-01-28 16:02:41 -0800940 except TypeError:
941 main.log.exception( self.name + ": Object not as expected" )
942 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400943 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800944 main.log.error( self.name + ": EOF exception found" )
945 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400946 main.cleanup()
947 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800949 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400950 main.cleanup()
951 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800954 """
andrewonlabe6745342014-10-17 14:29:13 -0400955 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 * hostIdOne: ONOS host id for host1
957 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400958 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800959 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500960 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800961 Returns:
962 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800963 """
andrewonlabe6745342014-10-17 14:29:13 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 cmdStr = "add-host-intent " + str( hostIdOne ) +\
966 " " + str( hostIdTwo )
967 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800968 if re.search( "Error", handle ):
969 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700970 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800971 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800972 else:
973 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800974 str( hostIdOne ) + " and " + str( hostIdTwo ) )
975 match = re.search('id=0x([\da-f]+),', handle)
976 if match:
977 return match.group()[3:-1]
978 else:
979 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700980 main.log.debug( "Response from ONOS was: " +
981 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800982 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800983 except TypeError:
984 main.log.exception( self.name + ": Object not as expected" )
985 return None
andrewonlabe6745342014-10-17 14:29:13 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400989 main.cleanup()
990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800992 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400993 main.cleanup()
994 main.exit()
995
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800997 """
andrewonlab7b31d232014-10-24 13:31:47 -0400998 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 * ingressDevice: device id of ingress device
1000 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001001 Optional:
1002 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001003 Description:
1004 Adds an optical intent by specifying an ingress and egress device
1005 Returns:
1006 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001007 """
andrewonlab7b31d232014-10-24 13:31:47 -04001008 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1010 " " + str( egressDevice )
1011 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001012 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001013 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001014 main.log.error( "Error in adding Optical intent" )
1015 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001016 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001017 main.log.info( "Optical intent installed between " +
1018 str( ingressDevice ) + " and " +
1019 str( egressDevice ) )
1020 match = re.search('id=0x([\da-f]+),', handle)
1021 if match:
1022 return match.group()[3:-1]
1023 else:
1024 main.log.error( "Error, intent ID not found" )
1025 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001026 except TypeError:
1027 main.log.exception( self.name + ": Object not as expected" )
1028 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001030 main.log.error( self.name + ": EOF exception found" )
1031 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001032 main.cleanup()
1033 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001034 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001035 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001036 main.cleanup()
1037 main.exit()
1038
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001040 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 ingressDevice,
1042 egressDevice,
1043 portIngress="",
1044 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001045 ethType="",
1046 ethSrc="",
1047 ethDst="",
1048 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001050 ipProto="",
1051 ipSrc="",
1052 ipDst="",
1053 tcpSrc="",
1054 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001055 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001056 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 * ingressDevice: device id of ingress device
1058 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001059 Optional:
1060 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001061 * ethSrc: specify ethSrc ( i.e. src mac addr )
1062 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001063 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001065 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001066 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001067 * ipSrc: specify ip source address
1068 * ipDst: specify ip destination address
1069 * tcpSrc: specify tcp source port
1070 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001071 Description:
kelvin8ec71442015-01-15 16:57:00 -08001072 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001073 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001074 Returns:
1075 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001076
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001078 options developers provide for point-to-point
1079 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001080 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001081 try:
kelvin8ec71442015-01-15 16:57:00 -08001082 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001083 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001085 and not ipProto and not ipSrc and not ipDst \
1086 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001087 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001088
andrewonlab289e4b72014-10-21 21:24:18 -04001089 else:
andrewonlab36af3822014-11-18 17:48:18 -05001090 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001091
andrewonlab0c0a6772014-10-22 12:31:18 -04001092 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001093 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001094 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001095 cmd += " --ethSrc " + str( ethSrc )
1096 if ethDst:
1097 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001098 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001099 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001101 cmd += " --lambda "
1102 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001103 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001104 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001106 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001107 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001108 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001109 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001110 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001111 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001112
kelvin8ec71442015-01-15 16:57:00 -08001113 # Check whether the user appended the port
1114 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 if "/" in ingressDevice:
1116 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001117 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001119 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001120 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001121 # Would it make sense to throw an exception and exit
1122 # the test?
1123 return None
andrewonlab36af3822014-11-18 17:48:18 -05001124
kelvin8ec71442015-01-15 16:57:00 -08001125 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 str( ingressDevice ) + "/" +\
1127 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 if "/" in egressDevice:
1130 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001131 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001133 main.log.error( "You must specify the egress port" )
1134 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001135
kelvin8ec71442015-01-15 16:57:00 -08001136 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 str( egressDevice ) + "/" +\
1138 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001139
kelvin-onlab898a6c62015-01-16 14:13:53 -08001140 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001141 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001142 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001143 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001144 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001145 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001146 # TODO: print out all the options in this message?
1147 main.log.info( "Point-to-point intent installed between " +
1148 str( ingressDevice ) + " and " +
1149 str( egressDevice ) )
1150 match = re.search('id=0x([\da-f]+),', handle)
1151 if match:
1152 return match.group()[3:-1]
1153 else:
1154 main.log.error( "Error, intent ID not found" )
1155 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001156 except TypeError:
1157 main.log.exception( self.name + ": Object not as expected" )
1158 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001160 main.log.error( self.name + ": EOF exception found" )
1161 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001162 main.cleanup()
1163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001166 main.cleanup()
1167 main.exit()
1168
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001170 self,
shahshreyac2f97072015-03-19 17:04:29 -07001171 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001173 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001175 ethType="",
1176 ethSrc="",
1177 ethDst="",
1178 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001180 ipProto="",
1181 ipSrc="",
1182 ipDst="",
1183 tcpSrc="",
1184 tcpDst="",
1185 setEthSrc="",
1186 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001187 """
shahshreyad0c80432014-12-04 16:56:05 -08001188 Note:
shahshreya70622b12015-03-19 17:19:00 -07001189 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001190 is same. That is, all ingress devices include port numbers
1191 with a "/" or all ingress devices could specify device
1192 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001193 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001194 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001195 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001197 Optional:
1198 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001199 * ethSrc: specify ethSrc ( i.e. src mac addr )
1200 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001201 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001203 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001204 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001205 * ipSrc: specify ip source address
1206 * ipDst: specify ip destination address
1207 * tcpSrc: specify tcp source port
1208 * tcpDst: specify tcp destination port
1209 * setEthSrc: action to Rewrite Source MAC Address
1210 * setEthDst: action to Rewrite Destination MAC Address
1211 Description:
kelvin8ec71442015-01-15 16:57:00 -08001212 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001213 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 Returns:
1215 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001216
Jon Halle3f39ff2015-01-13 11:50:53 -08001217 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001218 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001219 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001220 """
shahshreyad0c80432014-12-04 16:56:05 -08001221 try:
kelvin8ec71442015-01-15 16:57:00 -08001222 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001223 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001225 and not ipProto and not ipSrc and not ipDst\
1226 and not tcpSrc and not tcpDst and not setEthSrc\
1227 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001228 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001229
1230 else:
1231 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001232
shahshreyad0c80432014-12-04 16:56:05 -08001233 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001234 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001235 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001236 cmd += " --ethSrc " + str( ethSrc )
1237 if ethDst:
1238 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001239 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001240 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001242 cmd += " --lambda "
1243 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001244 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001245 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001246 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001247 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001248 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001249 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001250 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001251 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001252 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001253 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001255 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001256 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001257
kelvin8ec71442015-01-15 16:57:00 -08001258 # Check whether the user appended the port
1259 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001260
1261 if portIngressList is None:
1262 for ingressDevice in ingressDeviceList:
1263 if "/" in ingressDevice:
1264 cmd += " " + str( ingressDevice )
1265 else:
1266 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001267 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001268 # TODO: perhaps more meaningful return
1269 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001270 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001271 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001272 for ingressDevice, portIngress in zip( ingressDeviceList,
1273 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001274 cmd += " " + \
1275 str( ingressDevice ) + "/" +\
1276 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001277 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001278 main.log.error( "Device list and port list does not " +
1279 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001280 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 if "/" in egressDevice:
1282 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001283 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001284 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001285 main.log.error( "You must specify " +
1286 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001287 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001288
kelvin8ec71442015-01-15 16:57:00 -08001289 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 str( egressDevice ) + "/" +\
1291 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001292 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001293 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001294 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001295 main.log.error( "Error in adding multipoint-to-singlepoint " +
1296 "intent" )
1297 return None
shahshreyad0c80432014-12-04 16:56:05 -08001298 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001299 match = re.search('id=0x([\da-f]+),', handle)
1300 if match:
1301 return match.group()[3:-1]
1302 else:
1303 main.log.error( "Error, intent ID not found" )
1304 return None
1305 except TypeError:
1306 main.log.exception( self.name + ": Object not as expected" )
1307 return None
1308 except pexpect.EOF:
1309 main.log.error( self.name + ": EOF exception found" )
1310 main.log.error( self.name + ": " + self.handle.before )
1311 main.cleanup()
1312 main.exit()
1313 except Exception:
1314 main.log.exception( self.name + ": Uncaught exception!" )
1315 main.cleanup()
1316 main.exit()
1317
1318 def addSinglepointToMultipointIntent(
1319 self,
1320 ingressDevice,
1321 egressDeviceList,
1322 portIngress="",
1323 portEgressList=None,
1324 ethType="",
1325 ethSrc="",
1326 ethDst="",
1327 bandwidth="",
1328 lambdaAlloc=False,
1329 ipProto="",
1330 ipSrc="",
1331 ipDst="",
1332 tcpSrc="",
1333 tcpDst="",
1334 setEthSrc="",
1335 setEthDst="" ):
1336 """
1337 Note:
1338 This function assumes the format of all egress devices
1339 is same. That is, all egress devices include port numbers
1340 with a "/" or all egress devices could specify device
1341 ids and port numbers seperately.
1342 Required:
1343 * EgressDeviceList: List of device ids of egress device
1344 ( Atleast 2 eress devices required in the list )
1345 * ingressDevice: device id of ingress device
1346 Optional:
1347 * ethType: specify ethType
1348 * ethSrc: specify ethSrc ( i.e. src mac addr )
1349 * ethDst: specify ethDst ( i.e. dst mac addr )
1350 * bandwidth: specify bandwidth capacity of link
1351 * lambdaAlloc: if True, intent will allocate lambda
1352 for the specified intent
1353 * ipProto: specify ip protocol
1354 * ipSrc: specify ip source address
1355 * ipDst: specify ip destination address
1356 * tcpSrc: specify tcp source port
1357 * tcpDst: specify tcp destination port
1358 * setEthSrc: action to Rewrite Source MAC Address
1359 * setEthDst: action to Rewrite Destination MAC Address
1360 Description:
1361 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1362 specifying device id's and optional fields
1363 Returns:
1364 A string of the intent id or None on error
1365
1366 NOTE: This function may change depending on the
1367 options developers provide for singlepoint-to-multipoint
1368 intent via cli
1369 """
1370 try:
1371 # If there are no optional arguments
1372 if not ethType and not ethSrc and not ethDst\
1373 and not bandwidth and not lambdaAlloc\
1374 and not ipProto and not ipSrc and not ipDst\
1375 and not tcpSrc and not tcpDst and not setEthSrc\
1376 and not setEthDst:
1377 cmd = "add-single-to-multi-intent"
1378
1379 else:
1380 cmd = "add-single-to-multi-intent"
1381
1382 if ethType:
1383 cmd += " --ethType " + str( ethType )
1384 if ethSrc:
1385 cmd += " --ethSrc " + str( ethSrc )
1386 if ethDst:
1387 cmd += " --ethDst " + str( ethDst )
1388 if bandwidth:
1389 cmd += " --bandwidth " + str( bandwidth )
1390 if lambdaAlloc:
1391 cmd += " --lambda "
1392 if ipProto:
1393 cmd += " --ipProto " + str( ipProto )
1394 if ipSrc:
1395 cmd += " --ipSrc " + str( ipSrc )
1396 if ipDst:
1397 cmd += " --ipDst " + str( ipDst )
1398 if tcpSrc:
1399 cmd += " --tcpSrc " + str( tcpSrc )
1400 if tcpDst:
1401 cmd += " --tcpDst " + str( tcpDst )
1402 if setEthSrc:
1403 cmd += " --setEthSrc " + str( setEthSrc )
1404 if setEthDst:
1405 cmd += " --setEthDst " + str( setEthDst )
1406
1407 # Check whether the user appended the port
1408 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001409
kelvin-onlabb9408212015-04-01 13:34:04 -07001410 if "/" in ingressDevice:
1411 cmd += " " + str( ingressDevice )
1412 else:
1413 if not portIngress:
1414 main.log.error( "You must specify " +
1415 "the Ingress port" )
1416 return main.FALSE
1417
1418 cmd += " " +\
1419 str( ingressDevice ) + "/" +\
1420 str( portIngress )
1421
1422 if portEgressList is None:
1423 for egressDevice in egressDeviceList:
1424 if "/" in egressDevice:
1425 cmd += " " + str( egressDevice )
1426 else:
1427 main.log.error( "You must specify " +
1428 "the egress port" )
1429 # TODO: perhaps more meaningful return
1430 return main.FALSE
1431 else:
1432 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001433 for egressDevice, portEgress in zip( egressDeviceList,
1434 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001435 cmd += " " + \
1436 str( egressDevice ) + "/" +\
1437 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001438 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001439 main.log.error( "Device list and port list does not " +
1440 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001441 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001442 handle = self.sendline( cmd )
1443 # If error, return error message
1444 if re.search( "Error", handle ):
1445 main.log.error( "Error in adding singlepoint-to-multipoint " +
1446 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001447 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001448 else:
1449 match = re.search('id=0x([\da-f]+),', handle)
1450 if match:
1451 return match.group()[3:-1]
1452 else:
1453 main.log.error( "Error, intent ID not found" )
1454 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001455 except TypeError:
1456 main.log.exception( self.name + ": Object not as expected" )
1457 return None
shahshreyad0c80432014-12-04 16:56:05 -08001458 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001459 main.log.error( self.name + ": EOF exception found" )
1460 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001461 main.cleanup()
1462 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001463 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001464 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001465 main.cleanup()
1466 main.exit()
1467
Hari Krishna9e232602015-04-13 17:29:08 -07001468 def addMplsIntent(
1469 self,
1470 ingressDevice,
1471 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001472 ingressPort="",
1473 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001474 ethType="",
1475 ethSrc="",
1476 ethDst="",
1477 bandwidth="",
1478 lambdaAlloc=False,
1479 ipProto="",
1480 ipSrc="",
1481 ipDst="",
1482 tcpSrc="",
1483 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001484 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001485 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001486 priority=""):
1487 """
1488 Required:
1489 * ingressDevice: device id of ingress device
1490 * egressDevice: device id of egress device
1491 Optional:
1492 * ethType: specify ethType
1493 * ethSrc: specify ethSrc ( i.e. src mac addr )
1494 * ethDst: specify ethDst ( i.e. dst mac addr )
1495 * bandwidth: specify bandwidth capacity of link
1496 * lambdaAlloc: if True, intent will allocate lambda
1497 for the specified intent
1498 * ipProto: specify ip protocol
1499 * ipSrc: specify ip source address
1500 * ipDst: specify ip destination address
1501 * tcpSrc: specify tcp source port
1502 * tcpDst: specify tcp destination port
1503 * ingressLabel: Ingress MPLS label
1504 * egressLabel: Egress MPLS label
1505 Description:
1506 Adds MPLS intent by
1507 specifying device id's and optional fields
1508 Returns:
1509 A string of the intent id or None on error
1510
1511 NOTE: This function may change depending on the
1512 options developers provide for MPLS
1513 intent via cli
1514 """
1515 try:
1516 # If there are no optional arguments
1517 if not ethType and not ethSrc and not ethDst\
1518 and not bandwidth and not lambdaAlloc \
1519 and not ipProto and not ipSrc and not ipDst \
1520 and not tcpSrc and not tcpDst and not ingressLabel \
1521 and not egressLabel:
1522 cmd = "add-mpls-intent"
1523
1524 else:
1525 cmd = "add-mpls-intent"
1526
1527 if ethType:
1528 cmd += " --ethType " + str( ethType )
1529 if ethSrc:
1530 cmd += " --ethSrc " + str( ethSrc )
1531 if ethDst:
1532 cmd += " --ethDst " + str( ethDst )
1533 if bandwidth:
1534 cmd += " --bandwidth " + str( bandwidth )
1535 if lambdaAlloc:
1536 cmd += " --lambda "
1537 if ipProto:
1538 cmd += " --ipProto " + str( ipProto )
1539 if ipSrc:
1540 cmd += " --ipSrc " + str( ipSrc )
1541 if ipDst:
1542 cmd += " --ipDst " + str( ipDst )
1543 if tcpSrc:
1544 cmd += " --tcpSrc " + str( tcpSrc )
1545 if tcpDst:
1546 cmd += " --tcpDst " + str( tcpDst )
1547 if ingressLabel:
1548 cmd += " --ingressLabel " + str( ingressLabel )
1549 if egressLabel:
1550 cmd += " --egressLabel " + str( egressLabel )
1551 if priority:
1552 cmd += " --priority " + str( priority )
1553
1554 # Check whether the user appended the port
1555 # or provided it as an input
1556 if "/" in ingressDevice:
1557 cmd += " " + str( ingressDevice )
1558 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001559 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001560 main.log.error( "You must specify the ingress port" )
1561 return None
1562
1563 cmd += " " + \
1564 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001565 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001566
1567 if "/" in egressDevice:
1568 cmd += " " + str( egressDevice )
1569 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001570 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001571 main.log.error( "You must specify the egress port" )
1572 return None
1573
1574 cmd += " " +\
1575 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001576 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001577
1578 handle = self.sendline( cmd )
1579 # If error, return error message
1580 if re.search( "Error", handle ):
1581 main.log.error( "Error in adding mpls intent" )
1582 return None
1583 else:
1584 # TODO: print out all the options in this message?
1585 main.log.info( "MPLS intent installed between " +
1586 str( ingressDevice ) + " and " +
1587 str( egressDevice ) )
1588 match = re.search('id=0x([\da-f]+),', handle)
1589 if match:
1590 return match.group()[3:-1]
1591 else:
1592 main.log.error( "Error, intent ID not found" )
1593 return None
1594 except TypeError:
1595 main.log.exception( self.name + ": Object not as expected" )
1596 return None
1597 except pexpect.EOF:
1598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
1600 main.cleanup()
1601 main.exit()
1602 except Exception:
1603 main.log.exception( self.name + ": Uncaught exception!" )
1604 main.cleanup()
1605 main.exit()
1606
Jon Hallefbd9792015-03-05 16:11:36 -08001607 def removeIntent( self, intentId, app='org.onosproject.cli',
1608 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001609 """
shahshreya1c818fc2015-02-26 13:44:08 -08001610 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001611 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001612 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001613 -p or --purge: Purge the intent from the store after removal
1614
Jon Halle3f39ff2015-01-13 11:50:53 -08001615 Returns:
1616 main.False on error and
1617 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001618 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001619 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001620 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001621 if purge:
1622 cmdStr += " -p"
1623 if sync:
1624 cmdStr += " -s"
1625
1626 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001628 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001630 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001631 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001632 # TODO: Should this be main.TRUE
1633 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001634 except TypeError:
1635 main.log.exception( self.name + ": Object not as expected" )
1636 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001637 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001638 main.log.error( self.name + ": EOF exception found" )
1639 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001640 main.cleanup()
1641 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001642 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001643 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001644 main.cleanup()
1645 main.exit()
1646
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001647 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001648 """
1649 Purges all WITHDRAWN Intents
1650 """
1651 try:
1652 cmdStr = "purge-intents"
1653 handle = self.sendline( cmdStr )
1654 if re.search( "Error", handle ):
1655 main.log.error( "Error in purging intents" )
1656 return main.FALSE
1657 else:
1658 return main.TRUE
1659 except TypeError:
1660 main.log.exception( self.name + ": Object not as expected" )
1661 return None
1662 except pexpect.EOF:
1663 main.log.error( self.name + ": EOF exception found" )
1664 main.log.error( self.name + ": " + self.handle.before )
1665 main.cleanup()
1666 main.exit()
1667 except Exception:
1668 main.log.exception( self.name + ": Uncaught exception!" )
1669 main.cleanup()
1670 main.exit()
1671
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001673 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001674 NOTE: This method should be used after installing application:
1675 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001676 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001678 Description:
1679 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001680 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001681 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001682 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001683 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001684 cmdStr += " -j"
1685 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001686 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001687 except TypeError:
1688 main.log.exception( self.name + ": Object not as expected" )
1689 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001690 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001691 main.log.error( self.name + ": EOF exception found" )
1692 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001693 main.cleanup()
1694 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001695 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001696 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001697 main.cleanup()
1698 main.exit()
1699
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001701 """
andrewonlab377693f2014-10-21 16:00:30 -04001702 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001704 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001705 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001706 """
andrewonlabe6745342014-10-17 14:29:13 -04001707 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001708 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001709 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001710 cmdStr += " -j"
1711 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001712 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001713 except TypeError:
1714 main.log.exception( self.name + ": Object not as expected" )
1715 return None
andrewonlabe6745342014-10-17 14:29:13 -04001716 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001717 main.log.error( self.name + ": EOF exception found" )
1718 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001719 main.cleanup()
1720 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001721 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001722 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001723 main.cleanup()
1724 main.exit()
1725
kelvin-onlab54400a92015-02-26 18:05:51 -08001726 def getIntentState(self, intentsId, intentsJson=None):
1727 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001728 Check intent state.
1729 Accepts a single intent ID (string type) or a list of intent IDs.
1730 Returns the state(string type) of the id if a single intent ID is
1731 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001732 Returns a dictionary with intent IDs as the key and its
1733 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001734 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001735 intentId: intent ID (string type)
1736 intentsJson: parsed json object from the onos:intents api
1737 Returns:
1738 state = An intent's state- INSTALL,WITHDRAWN etc.
1739 stateDict = Dictionary of intent's state. intent ID as the keys and
1740 state as the values.
1741 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001742 try:
1743 state = "State is Undefined"
1744 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001745 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001746 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001747 intentsJsonTemp = json.loads( intentsJson )
1748 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001749 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001750 if intentsId == intent[ 'id' ]:
1751 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001752 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001753 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1754 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001755 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001756 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001757 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001758 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001759 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001760 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001761 if intentsId[ i ] == intents[ 'id' ]:
1762 stateDict[ 'state' ] = intents[ 'state' ]
1763 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001764 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001765 break
Jon Hallefbd9792015-03-05 16:11:36 -08001766 if len( intentsId ) != len( dictList ):
1767 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001768 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001769 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001770 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001771 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001772 except TypeError:
1773 main.log.exception( self.name + ": Object not as expected" )
1774 return None
1775 except pexpect.EOF:
1776 main.log.error( self.name + ": EOF exception found" )
1777 main.log.error( self.name + ": " + self.handle.before )
1778 main.cleanup()
1779 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001780 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001781 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001782 main.cleanup()
1783 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001784
kelvin-onlabf512e942015-06-08 19:42:59 -07001785 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001786 """
1787 Description:
1788 Check intents state
1789 Required:
1790 intentsId - List of intents ID to be checked
1791 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001792 expectedState - Check the expected state(s) of each intents
1793 state in the list.
1794 *NOTE: You can pass in a list of expected state,
1795 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001796 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001797 Returns main.TRUE only if all intent are the same as expected states
1798 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001799 """
1800 try:
1801 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001802 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001803 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001804
Jon Hall390696c2015-05-05 17:13:41 -07001805 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001806 if len( intentsId ) != len( intentsDict ):
1807 main.log.info( self.name + "There is something wrong " +
1808 "getting intents state" )
1809 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001810
1811 if isinstance( expectedState, types.StringType ):
1812 for intents in intentsDict:
1813 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001814 main.log.debug( self.name + " : Intent ID - " +
1815 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001816 " actual state = " +
1817 intents.get( 'state' )
1818 + " does not equal expected state = "
1819 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001820 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001821
1822 elif isinstance( expectedState, types.ListType ):
1823 for intents in intentsDict:
1824 if not any( state == intents.get( 'state' ) for state in
1825 expectedState ):
1826 main.log.debug( self.name + " : Intent ID - " +
1827 intents.get( 'id' ) +
1828 " actual state = " +
1829 intents.get( 'state' ) +
1830 " does not equal expected states = "
1831 + str( expectedState ) )
1832 returnValue = main.FALSE
1833
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001834 if returnValue == main.TRUE:
1835 main.log.info( self.name + ": All " +
1836 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001837 " intents are in " + str( expectedState ) +
1838 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001839 return returnValue
1840 except TypeError:
1841 main.log.exception( self.name + ": Object not as expected" )
1842 return None
1843 except pexpect.EOF:
1844 main.log.error( self.name + ": EOF exception found" )
1845 main.log.error( self.name + ": " + self.handle.before )
1846 main.cleanup()
1847 main.exit()
1848 except Exception:
1849 main.log.exception( self.name + ": Uncaught exception!" )
1850 main.cleanup()
1851 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001852
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001854 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001855 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001857 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001858 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001859 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001860 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001861 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001862 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001863 cmdStr += " -j"
1864 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001865 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001866 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001867 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001868 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001879 main.cleanup()
1880 main.exit()
1881
kelvin-onlab4df89f22015-04-13 18:10:23 -07001882 def checkFlowsState( self ):
1883 """
1884 Description:
1885 Check the if all the current flows are in ADDED state or
1886 PENDING_ADD state
1887 Return:
1888 returnValue - Returns main.TRUE only if all flows are in
1889 ADDED state or PENDING_ADD, return main.FALSE
1890 otherwise.
1891 """
1892 try:
1893 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001894 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001895 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001896
kelvin-onlab4df89f22015-04-13 18:10:23 -07001897 for device in tempFlows:
1898 for flow in device.get( 'flows' ):
1899 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1900 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001901
kelvin-onlab4df89f22015-04-13 18:10:23 -07001902 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001903 str( flow.get( 'groupId' ) ) +
1904 " | state:" +
1905 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001906 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001907
kelvin-onlab4df89f22015-04-13 18:10:23 -07001908 return returnValue
1909 except TypeError:
1910 main.log.exception( self.name + ": Object not as expected" )
1911 return None
1912 except pexpect.EOF:
1913 main.log.error( self.name + ": EOF exception found" )
1914 main.log.error( self.name + ": " + self.handle.before )
1915 main.cleanup()
1916 main.exit()
1917 except Exception:
1918 main.log.exception( self.name + ": Uncaught exception!" )
1919 main.cleanup()
1920 main.exit()
1921
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001923 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001924 """
andrewonlab87852b02014-11-19 18:44:19 -05001925 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001926 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001927 a specific point-to-point intent definition
1928 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 * dpidSrc: specify source dpid
1930 * dpidDst: specify destination dpid
1931 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001932 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001933 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001934 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001936 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001937 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001938 """
andrewonlab87852b02014-11-19 18:44:19 -05001939 try:
kelvin8ec71442015-01-15 16:57:00 -08001940 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001941 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1942 str( numIntents )
1943 if numMult:
1944 cmd += " " + str( numMult )
1945 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001946 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 if appId:
1948 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001949 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001950 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001951 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001952 main.log.info( handle )
1953 # Split result by newline
1954 newline = handle.split( "\r\r\n" )
1955 # Ignore the first object of list, which is empty
1956 newline = newline[ 1: ]
1957 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001958 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001959 result = result.split( ": " )
1960 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001961 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1962 main.log.info( latResult )
1963 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001964 else:
1965 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001966 except TypeError:
1967 main.log.exception( self.name + ": Object not as expected" )
1968 return None
andrewonlab87852b02014-11-19 18:44:19 -05001969 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001970 main.log.error( self.name + ": EOF exception found" )
1971 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001972 main.cleanup()
1973 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001974 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001975 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001976 main.cleanup()
1977 main.exit()
1978
kelvin-onlabd3b64892015-01-20 13:26:24 -08001979 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001980 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001981 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001982 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001983 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001984 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001985 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001986 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001987 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001988 cmdStr += " -j"
1989 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001990 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001991 except TypeError:
1992 main.log.exception( self.name + ": Object not as expected" )
1993 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001995 main.log.error( self.name + ": EOF exception found" )
1996 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001997 main.cleanup()
1998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002000 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002001 main.cleanup()
2002 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002003
kelvin-onlabd3b64892015-01-20 13:26:24 -08002004 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002005 """
2006 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002007 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002009 """
andrewonlab867212a2014-10-22 20:13:38 -04002010 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002011 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002012 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002013 cmdStr += " -j"
2014 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002015 if handle:
2016 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002017 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002018 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002019 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002020 else:
2021 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return None
andrewonlab867212a2014-10-22 20:13:38 -04002025 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002028 main.cleanup()
2029 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002031 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002032 main.cleanup()
2033 main.exit()
2034
kelvin8ec71442015-01-15 16:57:00 -08002035 # Wrapper functions ****************
2036 # Wrapper functions use existing driver
2037 # functions and extends their use case.
2038 # For example, we may use the output of
2039 # a normal driver function, and parse it
2040 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04002041
kelvin-onlabd3b64892015-01-20 13:26:24 -08002042 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002043 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002044 Description:
2045 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002046 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002047 try:
kelvin8ec71442015-01-15 16:57:00 -08002048 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002049 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002050 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002051
kelvin8ec71442015-01-15 16:57:00 -08002052 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002053 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2054 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002055 match = re.search('id=0x([\da-f]+),', intents)
2056 if match:
2057 tmpId = match.group()[3:-1]
2058 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002059 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002060
Jon Halld4d4b372015-01-28 16:02:41 -08002061 except TypeError:
2062 main.log.exception( self.name + ": Object not as expected" )
2063 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002064 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002065 main.log.error( self.name + ": EOF exception found" )
2066 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002067 main.cleanup()
2068 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002070 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002071 main.cleanup()
2072 main.exit()
2073
Jon Hall30b82fa2015-03-04 17:15:43 -08002074 def FlowAddedCount( self, deviceId ):
2075 """
2076 Determine the number of flow rules for the given device id that are
2077 in the added state
2078 """
2079 try:
2080 cmdStr = "flows any " + str( deviceId ) + " | " +\
2081 "grep 'state=ADDED' | wc -l"
2082 handle = self.sendline( cmdStr )
2083 return handle
2084 except pexpect.EOF:
2085 main.log.error( self.name + ": EOF exception found" )
2086 main.log.error( self.name + ": " + self.handle.before )
2087 main.cleanup()
2088 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002089 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002090 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002091 main.cleanup()
2092 main.exit()
2093
kelvin-onlabd3b64892015-01-20 13:26:24 -08002094 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002095 """
andrewonlab95ce8322014-10-13 14:12:04 -04002096 Use 'devices' function to obtain list of all devices
2097 and parse the result to obtain a list of all device
2098 id's. Returns this list. Returns empty list if no
2099 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002100 List is ordered sequentially
2101
andrewonlab95ce8322014-10-13 14:12:04 -04002102 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002103 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002104 the ids. By obtaining the list of device ids on the fly,
2105 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002106 """
andrewonlab95ce8322014-10-13 14:12:04 -04002107 try:
kelvin8ec71442015-01-15 16:57:00 -08002108 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002109 devicesStr = self.devices( jsonFormat=False )
2110 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002111
kelvin-onlabd3b64892015-01-20 13:26:24 -08002112 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002113 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002114 return idList
kelvin8ec71442015-01-15 16:57:00 -08002115
2116 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002117 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002118 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002119 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002120 # Split list further into arguments before and after string
2121 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002122 # append to idList
2123 for arg in tempList:
2124 idList.append( arg.split( "id=" )[ 1 ] )
2125 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002126
Jon Halld4d4b372015-01-28 16:02:41 -08002127 except TypeError:
2128 main.log.exception( self.name + ": Object not as expected" )
2129 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002130 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002131 main.log.error( self.name + ": EOF exception found" )
2132 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002133 main.cleanup()
2134 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002135 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002136 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002137 main.cleanup()
2138 main.exit()
2139
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002141 """
andrewonlab7c211572014-10-15 16:45:20 -04002142 Uses 'nodes' function to obtain list of all nodes
2143 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002144 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002145 Returns:
2146 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002147 """
andrewonlab7c211572014-10-15 16:45:20 -04002148 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002149 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002150 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002151 # Sample nodesStr output
2152 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002153 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002154 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002156 nodesJson = json.loads( nodesStr )
2157 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002158 return idList
kelvin8ec71442015-01-15 16:57:00 -08002159
Jon Halld4d4b372015-01-28 16:02:41 -08002160 except TypeError:
2161 main.log.exception( self.name + ": Object not as expected" )
2162 return None
andrewonlab7c211572014-10-15 16:45:20 -04002163 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002164 main.log.error( self.name + ": EOF exception found" )
2165 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002166 main.cleanup()
2167 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002168 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002169 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002170 main.cleanup()
2171 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002172
kelvin-onlabd3b64892015-01-20 13:26:24 -08002173 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002174 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002175 Return the first device from the devices api whose 'id' contains 'dpid'
2176 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002177 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002178 try:
kelvin8ec71442015-01-15 16:57:00 -08002179 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002180 return None
2181 else:
kelvin8ec71442015-01-15 16:57:00 -08002182 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002183 rawDevices = self.devices()
2184 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002185 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002186 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002187 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2188 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002189 return device
2190 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002191 except TypeError:
2192 main.log.exception( self.name + ": Object not as expected" )
2193 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002194 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002195 main.log.error( self.name + ": EOF exception found" )
2196 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002197 main.cleanup()
2198 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002199 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002200 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002201 main.cleanup()
2202 main.exit()
2203
kelvin-onlabd3b64892015-01-20 13:26:24 -08002204 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002205 """
Jon Hallefbd9792015-03-05 16:11:36 -08002206 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002207 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002208 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002209
Jon Hall42db6dc2014-10-24 19:03:48 -04002210 Params: ip = ip used for the onos cli
2211 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002212 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 logLevel = level to log to. Currently accepts
2214 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002215
2216
kelvin-onlabd3b64892015-01-20 13:26:24 -08002217 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002218
Jon Hallefbd9792015-03-05 16:11:36 -08002219 Returns: main.TRUE if the number of switches and links are correct,
2220 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002221 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002222 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002223 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002224 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002225 if topology == {}:
2226 return main.ERROR
2227 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002228 # Is the number of switches is what we expected
2229 devices = topology.get( 'devices', False )
2230 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002231 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002232 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002233 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002234 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 linkCheck = ( int( links ) == int( numolink ) )
2236 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002237 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002238 output += "The number of links and switches match " +\
2239 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002240 result = main.TRUE
2241 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002242 output += "The number of links and switches does not match " +\
2243 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002244 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002245 output = output + "\n ONOS sees %i devices (%i expected) \
2246 and %i links (%i expected)" % (
2247 int( devices ), int( numoswitch ), int( links ),
2248 int( numolink ) )
2249 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002250 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002252 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002253 else:
Jon Hall390696c2015-05-05 17:13:41 -07002254 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002255 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002256 except TypeError:
2257 main.log.exception( self.name + ": Object not as expected" )
2258 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002260 main.log.error( self.name + ": EOF exception found" )
2261 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002262 main.cleanup()
2263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002265 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002266 main.cleanup()
2267 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002268
kelvin-onlabd3b64892015-01-20 13:26:24 -08002269 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002270 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002271 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 deviceId must be the id of a device as seen in the onos devices command
2273 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002274 role must be either master, standby, or none
2275
Jon Halle3f39ff2015-01-13 11:50:53 -08002276 Returns:
2277 main.TRUE or main.FALSE based on argument verification and
2278 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002279 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002280 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002281 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002282 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002283 cmdStr = "device-role " +\
2284 str( deviceId ) + " " +\
2285 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002286 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002287 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 if re.search( "Error", handle ):
2289 # end color output to escape any colours
2290 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002291 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002292 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002293 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002294 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002295 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002296 main.log.error( "Invalid 'role' given to device_role(). " +
2297 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002298 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002302 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002303 main.log.error( self.name + ": EOF exception found" )
2304 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002305 main.cleanup()
2306 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002307 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002308 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002309 main.cleanup()
2310 main.exit()
2311
kelvin-onlabd3b64892015-01-20 13:26:24 -08002312 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002313 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002314 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002315 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002316 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002317 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002318 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002319 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002320 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002321 cmdStr += " -j"
2322 handle = self.sendline( cmdStr )
2323 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002324 except TypeError:
2325 main.log.exception( self.name + ": Object not as expected" )
2326 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002327 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002328 main.log.error( self.name + ": EOF exception found" )
2329 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002330 main.cleanup()
2331 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002332 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002333 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002334 main.cleanup()
2335 main.exit()
2336
kelvin-onlabd3b64892015-01-20 13:26:24 -08002337 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002338 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002339 CLI command to get the current leader for the Election test application
2340 NOTE: Requires installation of the onos-app-election feature
2341 Returns: Node IP of the leader if one exists
2342 None if none exists
2343 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002344 """
Jon Hall94fd0472014-12-08 11:52:42 -08002345 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002346 cmdStr = "election-test-leader"
2347 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002348 # Leader
2349 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002350 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002351 nodeSearch = re.search( leaderPattern, response )
2352 if nodeSearch:
2353 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002354 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002355 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002356 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002357 # no leader
2358 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002359 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002360 nullSearch = re.search( nullPattern, response )
2361 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002362 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002363 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002364 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002365 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002366 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002367 if re.search( errorPattern, response ):
2368 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002369 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002370 return main.FALSE
2371 else:
Jon Hall390696c2015-05-05 17:13:41 -07002372 main.log.error( "Error in electionTestLeader on " + self.name +
2373 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002374 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002375 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002376 except TypeError:
2377 main.log.exception( self.name + ": Object not as expected" )
2378 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002379 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002380 main.log.error( self.name + ": EOF exception found" )
2381 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002382 main.cleanup()
2383 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002384 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002385 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002386 main.cleanup()
2387 main.exit()
2388
kelvin-onlabd3b64892015-01-20 13:26:24 -08002389 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002390 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002391 CLI command to run for leadership of the Election test application.
2392 NOTE: Requires installation of the onos-app-election feature
2393 Returns: Main.TRUE on success
2394 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002395 """
Jon Hall94fd0472014-12-08 11:52:42 -08002396 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002397 cmdStr = "election-test-run"
2398 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002399 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002400 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002401 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002402 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002403 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002404 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002405 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002406 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002407 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002408 errorPattern = "Command\snot\sfound"
2409 if re.search( errorPattern, response ):
2410 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002411 return main.FALSE
2412 else:
Jon Hall390696c2015-05-05 17:13:41 -07002413 main.log.error( "Error in electionTestRun on " + self.name +
2414 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002415 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002416 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002417 except TypeError:
2418 main.log.exception( self.name + ": Object not as expected" )
2419 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002420 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002421 main.log.error( self.name + ": EOF exception found" )
2422 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002423 main.cleanup()
2424 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002425 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002426 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002427 main.cleanup()
2428 main.exit()
2429
kelvin-onlabd3b64892015-01-20 13:26:24 -08002430 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002431 """
Jon Hall94fd0472014-12-08 11:52:42 -08002432 * CLI command to withdraw the local node from leadership election for
2433 * the Election test application.
2434 #NOTE: Requires installation of the onos-app-election feature
2435 Returns: Main.TRUE on success
2436 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002437 """
Jon Hall94fd0472014-12-08 11:52:42 -08002438 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002439 cmdStr = "election-test-withdraw"
2440 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002441 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002442 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002443 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002444 if re.search( successPattern, response ):
2445 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002446 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002447 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002448 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002449 errorPattern = "Command\snot\sfound"
2450 if re.search( errorPattern, response ):
2451 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002452 return main.FALSE
2453 else:
Jon Hall390696c2015-05-05 17:13:41 -07002454 main.log.error( "Error in electionTestWithdraw on " +
2455 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002456 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002457 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002458 except TypeError:
2459 main.log.exception( self.name + ": Object not as expected" )
2460 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002461 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002462 main.log.error( self.name + ": EOF exception found" )
2463 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002464 main.cleanup()
2465 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002466 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002467 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002468 main.cleanup()
2469 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002470
kelvin8ec71442015-01-15 16:57:00 -08002471 def getDevicePortsEnabledCount( self, dpid ):
2472 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002473 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002474 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002475 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002476 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002477 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2478 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002479 if re.search( "No such device", output ):
2480 main.log.error( "Error in getting ports" )
2481 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002482 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002483 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002484 except TypeError:
2485 main.log.exception( self.name + ": Object not as expected" )
2486 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002487 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002488 main.log.error( self.name + ": EOF exception found" )
2489 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002490 main.cleanup()
2491 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002493 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002494 main.cleanup()
2495 main.exit()
2496
kelvin8ec71442015-01-15 16:57:00 -08002497 def getDeviceLinksActiveCount( self, dpid ):
2498 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002499 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002500 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002501 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002502 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002503 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2504 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002505 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002506 main.log.error( "Error in getting ports " )
2507 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002508 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002509 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002510 except TypeError:
2511 main.log.exception( self.name + ": Object not as expected" )
2512 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002513 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002514 main.log.error( self.name + ": EOF exception found" )
2515 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002516 main.cleanup()
2517 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002518 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002519 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002520 main.cleanup()
2521 main.exit()
2522
kelvin8ec71442015-01-15 16:57:00 -08002523 def getAllIntentIds( self ):
2524 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002525 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002526 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002527 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002528 cmdStr = "onos:intents | grep id="
2529 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002530 if re.search( "Error", output ):
2531 main.log.error( "Error in getting ports" )
2532 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002533 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002534 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002535 except TypeError:
2536 main.log.exception( self.name + ": Object not as expected" )
2537 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002539 main.log.error( self.name + ": EOF exception found" )
2540 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002541 main.cleanup()
2542 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002543 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002544 main.log.exception( self.name + ": Uncaught exception!" )
2545 main.cleanup()
2546 main.exit()
2547
Jon Hall73509952015-02-24 16:42:56 -08002548 def intentSummary( self ):
2549 """
Jon Hallefbd9792015-03-05 16:11:36 -08002550 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002551 """
2552 try:
2553 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002554 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002555 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002556 states.append( intent.get( 'state', None ) )
2557 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002558 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002559 return dict( out )
2560 except TypeError:
2561 main.log.exception( self.name + ": Object not as expected" )
2562 return None
2563 except pexpect.EOF:
2564 main.log.error( self.name + ": EOF exception found" )
2565 main.log.error( self.name + ": " + self.handle.before )
2566 main.cleanup()
2567 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002568 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002569 main.log.exception( self.name + ": Uncaught exception!" )
2570 main.cleanup()
2571 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002572
Jon Hall61282e32015-03-19 11:34:11 -07002573 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002574 """
2575 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002576 Optional argument:
2577 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002578 """
Jon Hall63604932015-02-26 17:09:50 -08002579 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002580 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002581 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002582 cmdStr += " -j"
2583 output = self.sendline( cmdStr )
2584 return output
Jon Hall63604932015-02-26 17:09:50 -08002585 except TypeError:
2586 main.log.exception( self.name + ": Object not as expected" )
2587 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002588 except pexpect.EOF:
2589 main.log.error( self.name + ": EOF exception found" )
2590 main.log.error( self.name + ": " + self.handle.before )
2591 main.cleanup()
2592 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002593 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002594 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002595 main.cleanup()
2596 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002597
acsmarsa4a4d1e2015-07-10 16:01:24 -07002598 def leaderCandidates( self, jsonFormat=True ):
2599 """
2600 Returns the output of the leaders -c command.
2601 Optional argument:
2602 * jsonFormat - boolean indicating if you want output in json
2603 """
2604 try:
2605 cmdStr = "onos:leaders -c"
2606 if jsonFormat:
2607 cmdStr += " -j"
2608 output = self.sendline( cmdStr )
2609 return output
2610 except TypeError:
2611 main.log.exception( self.name + ": Object not as expected" )
2612 return None
2613 except pexpect.EOF:
2614 main.log.error( self.name + ": EOF exception found" )
2615 main.log.error( self.name + ": " + self.handle.before )
2616 main.cleanup()
2617 main.exit()
2618 except Exception:
2619 main.log.exception( self.name + ": Uncaught exception!" )
2620 main.cleanup()
2621 main.exit()
2622
2623 def specificLeaderCandidate(self,topic):
2624 """
2625 Returns a list in format [leader,candidate1,candidate2,...] for a given
2626 topic parameter and an empty list if the topic doesn't exist
2627 If no leader is elected leader in the returned list will be "none"
2628 Returns None if there is a type error processing the json object
2629 """
2630 try:
2631 cmdStr = "onos:leaders -c -j"
2632 output = self.sendline( cmdStr )
2633 output = json.loads(output)
2634 results = []
2635 for dict in output:
2636 if dict["topic"] == topic:
2637 leader = dict["leader"]
2638 candidates = re.split(", ",dict["candidates"][1:-1])
2639 results.append(leader)
2640 results.extend(candidates)
2641 return results
2642 except TypeError:
2643 main.log.exception( self.name + ": Object not as expected" )
2644 return None
2645 except pexpect.EOF:
2646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
2648 main.cleanup()
2649 main.exit()
2650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
2652 main.cleanup()
2653 main.exit()
2654
Jon Hall61282e32015-03-19 11:34:11 -07002655 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002656 """
2657 Returns the output of the intent Pending map.
2658 """
Jon Hall63604932015-02-26 17:09:50 -08002659 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002660 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002661 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002662 cmdStr += " -j"
2663 output = self.sendline( cmdStr )
2664 return output
Jon Hall63604932015-02-26 17:09:50 -08002665 except TypeError:
2666 main.log.exception( self.name + ": Object not as expected" )
2667 return None
2668 except pexpect.EOF:
2669 main.log.error( self.name + ": EOF exception found" )
2670 main.log.error( self.name + ": " + self.handle.before )
2671 main.cleanup()
2672 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002673 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002674 main.log.exception( self.name + ": Uncaught exception!" )
2675 main.cleanup()
2676 main.exit()
2677
Jon Hall61282e32015-03-19 11:34:11 -07002678 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002679 """
2680 Returns the output of the raft partitions command for ONOS.
2681 """
Jon Hall61282e32015-03-19 11:34:11 -07002682 # Sample JSON
2683 # {
2684 # "leader": "tcp://10.128.30.11:7238",
2685 # "members": [
2686 # "tcp://10.128.30.11:7238",
2687 # "tcp://10.128.30.17:7238",
2688 # "tcp://10.128.30.13:7238",
2689 # ],
2690 # "name": "p1",
2691 # "term": 3
2692 # },
Jon Hall63604932015-02-26 17:09:50 -08002693 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002694 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002695 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002696 cmdStr += " -j"
2697 output = self.sendline( cmdStr )
2698 return output
Jon Hall63604932015-02-26 17:09:50 -08002699 except TypeError:
2700 main.log.exception( self.name + ": Object not as expected" )
2701 return None
2702 except pexpect.EOF:
2703 main.log.error( self.name + ": EOF exception found" )
2704 main.log.error( self.name + ": " + self.handle.before )
2705 main.cleanup()
2706 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002707 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002708 main.log.exception( self.name + ": Uncaught exception!" )
2709 main.cleanup()
2710 main.exit()
2711
Jon Hallbe379602015-03-24 13:39:32 -07002712 def apps( self, jsonFormat=True ):
2713 """
2714 Returns the output of the apps command for ONOS. This command lists
2715 information about installed ONOS applications
2716 """
2717 # Sample JSON object
2718 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2719 # "description":"ONOS OpenFlow protocol southbound providers",
2720 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2721 # "features":"[onos-openflow]","state":"ACTIVE"}]
2722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002723 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002725 cmdStr += " -j"
2726 output = self.sendline( cmdStr )
2727 assert "Error executing command" not in output
2728 return output
Jon Hallbe379602015-03-24 13:39:32 -07002729 # FIXME: look at specific exceptions/Errors
2730 except AssertionError:
2731 main.log.error( "Error in processing onos:app command: " +
2732 str( output ) )
2733 return None
2734 except TypeError:
2735 main.log.exception( self.name + ": Object not as expected" )
2736 return None
2737 except pexpect.EOF:
2738 main.log.error( self.name + ": EOF exception found" )
2739 main.log.error( self.name + ": " + self.handle.before )
2740 main.cleanup()
2741 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002742 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002743 main.log.exception( self.name + ": Uncaught exception!" )
2744 main.cleanup()
2745 main.exit()
2746
Jon Hall146f1522015-03-24 15:33:24 -07002747 def appStatus( self, appName ):
2748 """
2749 Uses the onos:apps cli command to return the status of an application.
2750 Returns:
2751 "ACTIVE" - If app is installed and activated
2752 "INSTALLED" - If app is installed and deactivated
2753 "UNINSTALLED" - If app is not installed
2754 None - on error
2755 """
Jon Hall146f1522015-03-24 15:33:24 -07002756 try:
2757 if not isinstance( appName, types.StringType ):
2758 main.log.error( self.name + ".appStatus(): appName must be" +
2759 " a string" )
2760 return None
2761 output = self.apps( jsonFormat=True )
2762 appsJson = json.loads( output )
2763 state = None
2764 for app in appsJson:
2765 if appName == app.get('name'):
2766 state = app.get('state')
2767 break
2768 if state == "ACTIVE" or state == "INSTALLED":
2769 return state
2770 elif state is None:
2771 return "UNINSTALLED"
2772 elif state:
2773 main.log.error( "Unexpected state from 'onos:apps': " +
2774 str( state ) )
2775 return state
2776 except TypeError:
2777 main.log.exception( self.name + ": Object not as expected" )
2778 return None
2779 except pexpect.EOF:
2780 main.log.error( self.name + ": EOF exception found" )
2781 main.log.error( self.name + ": " + self.handle.before )
2782 main.cleanup()
2783 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002784 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002785 main.log.exception( self.name + ": Uncaught exception!" )
2786 main.cleanup()
2787 main.exit()
2788
Jon Hallbe379602015-03-24 13:39:32 -07002789 def app( self, appName, option ):
2790 """
2791 Interacts with the app command for ONOS. This command manages
2792 application inventory.
2793 """
Jon Hallbe379602015-03-24 13:39:32 -07002794 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002795 # Validate argument types
2796 valid = True
2797 if not isinstance( appName, types.StringType ):
2798 main.log.error( self.name + ".app(): appName must be a " +
2799 "string" )
2800 valid = False
2801 if not isinstance( option, types.StringType ):
2802 main.log.error( self.name + ".app(): option must be a string" )
2803 valid = False
2804 if not valid:
2805 return main.FALSE
2806 # Validate Option
2807 option = option.lower()
2808 # NOTE: Install may become a valid option
2809 if option == "activate":
2810 pass
2811 elif option == "deactivate":
2812 pass
2813 elif option == "uninstall":
2814 pass
2815 else:
2816 # Invalid option
2817 main.log.error( "The ONOS app command argument only takes " +
2818 "the values: (activate|deactivate|uninstall)" +
2819 "; was given '" + option + "'")
2820 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002821 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002822 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002823 if "Error executing command" in output:
2824 main.log.error( "Error in processing onos:app command: " +
2825 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002826 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002827 elif "No such application" in output:
2828 main.log.error( "The application '" + appName +
2829 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002830 return main.FALSE
2831 elif "Command not found:" in output:
2832 main.log.error( "Error in processing onos:app command: " +
2833 str( output ) )
2834 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002835 elif "Unsupported command:" in output:
2836 main.log.error( "Incorrect command given to 'app': " +
2837 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002838 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002839 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002840 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002841 return main.TRUE
2842 except TypeError:
2843 main.log.exception( self.name + ": Object not as expected" )
2844 return main.ERROR
2845 except pexpect.EOF:
2846 main.log.error( self.name + ": EOF exception found" )
2847 main.log.error( self.name + ": " + self.handle.before )
2848 main.cleanup()
2849 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002850 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002851 main.log.exception( self.name + ": Uncaught exception!" )
2852 main.cleanup()
2853 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002854
Jon Hallbd16b922015-03-26 17:53:15 -07002855 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002856 """
2857 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002858 appName is the hierarchical app name, not the feature name
2859 If check is True, method will check the status of the app after the
2860 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002861 Returns main.TRUE if the command was successfully sent
2862 main.FALSE if the cli responded with an error or given
2863 incorrect input
2864 """
2865 try:
2866 if not isinstance( appName, types.StringType ):
2867 main.log.error( self.name + ".activateApp(): appName must be" +
2868 " a string" )
2869 return main.FALSE
2870 status = self.appStatus( appName )
2871 if status == "INSTALLED":
2872 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002873 if check and response == main.TRUE:
2874 for i in range(10): # try 10 times then give up
2875 # TODO: Check with Thomas about this delay
2876 status = self.appStatus( appName )
2877 if status == "ACTIVE":
2878 return main.TRUE
2879 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002880 main.log.debug( "The state of application " +
2881 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002882 time.sleep( 1 )
2883 return main.FALSE
2884 else: # not 'check' or command didn't succeed
2885 return response
Jon Hall146f1522015-03-24 15:33:24 -07002886 elif status == "ACTIVE":
2887 return main.TRUE
2888 elif status == "UNINSTALLED":
2889 main.log.error( self.name + ": Tried to activate the " +
2890 "application '" + appName + "' which is not " +
2891 "installed." )
2892 else:
2893 main.log.error( "Unexpected return value from appStatus: " +
2894 str( status ) )
2895 return main.ERROR
2896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return main.ERROR
2899 except pexpect.EOF:
2900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
2902 main.cleanup()
2903 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002904 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002905 main.log.exception( self.name + ": Uncaught exception!" )
2906 main.cleanup()
2907 main.exit()
2908
Jon Hallbd16b922015-03-26 17:53:15 -07002909 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002910 """
2911 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002912 appName is the hierarchical app name, not the feature name
2913 If check is True, method will check the status of the app after the
2914 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002915 Returns main.TRUE if the command was successfully sent
2916 main.FALSE if the cli responded with an error or given
2917 incorrect input
2918 """
2919 try:
2920 if not isinstance( appName, types.StringType ):
2921 main.log.error( self.name + ".deactivateApp(): appName must " +
2922 "be a string" )
2923 return main.FALSE
2924 status = self.appStatus( appName )
2925 if status == "INSTALLED":
2926 return main.TRUE
2927 elif status == "ACTIVE":
2928 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002929 if check and response == main.TRUE:
2930 for i in range(10): # try 10 times then give up
2931 status = self.appStatus( appName )
2932 if status == "INSTALLED":
2933 return main.TRUE
2934 else:
2935 time.sleep( 1 )
2936 return main.FALSE
2937 else: # not check or command didn't succeed
2938 return response
Jon Hall146f1522015-03-24 15:33:24 -07002939 elif status == "UNINSTALLED":
2940 main.log.warn( self.name + ": Tried to deactivate the " +
2941 "application '" + appName + "' which is not " +
2942 "installed." )
2943 return main.TRUE
2944 else:
2945 main.log.error( "Unexpected return value from appStatus: " +
2946 str( status ) )
2947 return main.ERROR
2948 except TypeError:
2949 main.log.exception( self.name + ": Object not as expected" )
2950 return main.ERROR
2951 except pexpect.EOF:
2952 main.log.error( self.name + ": EOF exception found" )
2953 main.log.error( self.name + ": " + self.handle.before )
2954 main.cleanup()
2955 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002956 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002957 main.log.exception( self.name + ": Uncaught exception!" )
2958 main.cleanup()
2959 main.exit()
2960
Jon Hallbd16b922015-03-26 17:53:15 -07002961 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002962 """
2963 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002964 appName is the hierarchical app name, not the feature name
2965 If check is True, method will check the status of the app after the
2966 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002967 Returns main.TRUE if the command was successfully sent
2968 main.FALSE if the cli responded with an error or given
2969 incorrect input
2970 """
2971 # TODO: check with Thomas about the state machine for apps
2972 try:
2973 if not isinstance( appName, types.StringType ):
2974 main.log.error( self.name + ".uninstallApp(): appName must " +
2975 "be a string" )
2976 return main.FALSE
2977 status = self.appStatus( appName )
2978 if status == "INSTALLED":
2979 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002980 if check and response == main.TRUE:
2981 for i in range(10): # try 10 times then give up
2982 status = self.appStatus( appName )
2983 if status == "UNINSTALLED":
2984 return main.TRUE
2985 else:
2986 time.sleep( 1 )
2987 return main.FALSE
2988 else: # not check or command didn't succeed
2989 return response
Jon Hall146f1522015-03-24 15:33:24 -07002990 elif status == "ACTIVE":
2991 main.log.warn( self.name + ": Tried to uninstall the " +
2992 "application '" + appName + "' which is " +
2993 "currently active." )
2994 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002995 if check and response == main.TRUE:
2996 for i in range(10): # try 10 times then give up
2997 status = self.appStatus( appName )
2998 if status == "UNINSTALLED":
2999 return main.TRUE
3000 else:
3001 time.sleep( 1 )
3002 return main.FALSE
3003 else: # not check or command didn't succeed
3004 return response
Jon Hall146f1522015-03-24 15:33:24 -07003005 elif status == "UNINSTALLED":
3006 return main.TRUE
3007 else:
3008 main.log.error( "Unexpected return value from appStatus: " +
3009 str( status ) )
3010 return main.ERROR
3011 except TypeError:
3012 main.log.exception( self.name + ": Object not as expected" )
3013 return main.ERROR
3014 except pexpect.EOF:
3015 main.log.error( self.name + ": EOF exception found" )
3016 main.log.error( self.name + ": " + self.handle.before )
3017 main.cleanup()
3018 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003019 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003020 main.log.exception( self.name + ": Uncaught exception!" )
3021 main.cleanup()
3022 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003023
3024 def appIDs( self, jsonFormat=True ):
3025 """
3026 Show the mappings between app id and app names given by the 'app-ids'
3027 cli command
3028 """
3029 try:
3030 cmdStr = "app-ids"
3031 if jsonFormat:
3032 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003033 output = self.sendline( cmdStr )
3034 assert "Error executing command" not in output
3035 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003036 except AssertionError:
3037 main.log.error( "Error in processing onos:app-ids command: " +
3038 str( output ) )
3039 return None
3040 except TypeError:
3041 main.log.exception( self.name + ": Object not as expected" )
3042 return None
3043 except pexpect.EOF:
3044 main.log.error( self.name + ": EOF exception found" )
3045 main.log.error( self.name + ": " + self.handle.before )
3046 main.cleanup()
3047 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003048 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003049 main.log.exception( self.name + ": Uncaught exception!" )
3050 main.cleanup()
3051 main.exit()
3052
3053 def appToIDCheck( self ):
3054 """
3055 This method will check that each application's ID listed in 'apps' is
3056 the same as the ID listed in 'app-ids'. The check will also check that
3057 there are no duplicate IDs issued. Note that an app ID should be
3058 a globaly unique numerical identifier for app/app-like features. Once
3059 an ID is registered, the ID is never freed up so that if an app is
3060 reinstalled it will have the same ID.
3061
3062 Returns: main.TRUE if the check passes and
3063 main.FALSE if the check fails or
3064 main.ERROR if there is some error in processing the test
3065 """
3066 try:
Jon Hall390696c2015-05-05 17:13:41 -07003067 bail = False
3068 ids = self.appIDs( jsonFormat=True )
3069 if ids:
3070 ids = json.loads( ids )
3071 else:
3072 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3073 bail = True
3074 apps = self.apps( jsonFormat=True )
3075 if apps:
3076 apps = json.loads( apps )
3077 else:
3078 main.log.error( "apps returned nothing:" + repr( apps ) )
3079 bail = True
3080 if bail:
3081 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003082 result = main.TRUE
3083 for app in apps:
3084 appID = app.get( 'id' )
3085 if appID is None:
3086 main.log.error( "Error parsing app: " + str( app ) )
3087 result = main.FALSE
3088 appName = app.get( 'name' )
3089 if appName is None:
3090 main.log.error( "Error parsing app: " + str( app ) )
3091 result = main.FALSE
3092 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003093 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003094 # main.log.debug( "Comparing " + str( app ) + " to " +
3095 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003096 if not current: # if ids doesn't have this id
3097 result = main.FALSE
3098 main.log.error( "'app-ids' does not have the ID for " +
3099 str( appName ) + " that apps does." )
3100 elif len( current ) > 1:
3101 # there is more than one app with this ID
3102 result = main.FALSE
3103 # We will log this later in the method
3104 elif not current[0][ 'name' ] == appName:
3105 currentName = current[0][ 'name' ]
3106 result = main.FALSE
3107 main.log.error( "'app-ids' has " + str( currentName ) +
3108 " registered under id:" + str( appID ) +
3109 " but 'apps' has " + str( appName ) )
3110 else:
3111 pass # id and name match!
3112 # now make sure that app-ids has no duplicates
3113 idsList = []
3114 namesList = []
3115 for item in ids:
3116 idsList.append( item[ 'id' ] )
3117 namesList.append( item[ 'name' ] )
3118 if len( idsList ) != len( set( idsList ) ) or\
3119 len( namesList ) != len( set( namesList ) ):
3120 main.log.error( "'app-ids' has some duplicate entries: \n"
3121 + json.dumps( ids,
3122 sort_keys=True,
3123 indent=4,
3124 separators=( ',', ': ' ) ) )
3125 result = main.FALSE
3126 return result
3127 except ( ValueError, TypeError ):
3128 main.log.exception( self.name + ": Object not as expected" )
3129 return main.ERROR
3130 except pexpect.EOF:
3131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
3133 main.cleanup()
3134 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003135 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003136 main.log.exception( self.name + ": Uncaught exception!" )
3137 main.cleanup()
3138 main.exit()
3139
Jon Hallfb760a02015-04-13 15:35:03 -07003140 def getCfg( self, component=None, propName=None, short=False,
3141 jsonFormat=True ):
3142 """
3143 Get configuration settings from onos cli
3144 Optional arguments:
3145 component - Optionally only list configurations for a specific
3146 component. If None, all components with configurations
3147 are displayed. Case Sensitive string.
3148 propName - If component is specified, propName option will show
3149 only this specific configuration from that component.
3150 Case Sensitive string.
3151 jsonFormat - Returns output as json. Note that this will override
3152 the short option
3153 short - Short, less verbose, version of configurations.
3154 This is overridden by the json option
3155 returns:
3156 Output from cli as a string or None on error
3157 """
3158 try:
3159 baseStr = "cfg"
3160 cmdStr = " get"
3161 componentStr = ""
3162 if component:
3163 componentStr += " " + component
3164 if propName:
3165 componentStr += " " + propName
3166 if jsonFormat:
3167 baseStr += " -j"
3168 elif short:
3169 baseStr += " -s"
3170 output = self.sendline( baseStr + cmdStr + componentStr )
3171 assert "Error executing command" not in output
3172 return output
3173 except AssertionError:
3174 main.log.error( "Error in processing 'cfg get' command: " +
3175 str( output ) )
3176 return None
3177 except TypeError:
3178 main.log.exception( self.name + ": Object not as expected" )
3179 return None
3180 except pexpect.EOF:
3181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
3183 main.cleanup()
3184 main.exit()
3185 except Exception:
3186 main.log.exception( self.name + ": Uncaught exception!" )
3187 main.cleanup()
3188 main.exit()
3189
3190 def setCfg( self, component, propName, value=None, check=True ):
3191 """
3192 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003193 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003194 component - The case sensitive name of the component whose
3195 property is to be set
3196 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003197 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003198 value - The value to set the property to. If None, will unset the
3199 property and revert it to it's default value(if applicable)
3200 check - Boolean, Check whether the option was successfully set this
3201 only applies when a value is given.
3202 returns:
3203 main.TRUE on success or main.FALSE on failure. If check is False,
3204 will return main.TRUE unless there is an error
3205 """
3206 try:
3207 baseStr = "cfg"
3208 cmdStr = " set " + str( component ) + " " + str( propName )
3209 if value is not None:
3210 cmdStr += " " + str( value )
3211 output = self.sendline( baseStr + cmdStr )
3212 assert "Error executing command" not in output
3213 if value and check:
3214 results = self.getCfg( component=str( component ),
3215 propName=str( propName ),
3216 jsonFormat=True )
3217 # Check if current value is what we just set
3218 try:
3219 jsonOutput = json.loads( results )
3220 current = jsonOutput[ 'value' ]
3221 except ( ValueError, TypeError ):
3222 main.log.exception( "Error parsing cfg output" )
3223 main.log.error( "output:" + repr( results ) )
3224 return main.FALSE
3225 if current == str( value ):
3226 return main.TRUE
3227 return main.FALSE
3228 return main.TRUE
3229 except AssertionError:
3230 main.log.error( "Error in processing 'cfg set' command: " +
3231 str( output ) )
3232 return main.FALSE
3233 except TypeError:
3234 main.log.exception( self.name + ": Object not as expected" )
3235 return main.FALSE
3236 except pexpect.EOF:
3237 main.log.error( self.name + ": EOF exception found" )
3238 main.log.error( self.name + ": " + self.handle.before )
3239 main.cleanup()
3240 main.exit()
3241 except Exception:
3242 main.log.exception( self.name + ": Uncaught exception!" )
3243 main.cleanup()
3244 main.exit()
3245
Jon Hall390696c2015-05-05 17:13:41 -07003246 def setTestAdd( self, setName, values ):
3247 """
3248 CLI command to add elements to a distributed set.
3249 Arguments:
3250 setName - The name of the set to add to.
3251 values - The value(s) to add to the set, space seperated.
3252 Example usages:
3253 setTestAdd( "set1", "a b c" )
3254 setTestAdd( "set2", "1" )
3255 returns:
3256 main.TRUE on success OR
3257 main.FALSE if elements were already in the set OR
3258 main.ERROR on error
3259 """
3260 try:
3261 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3262 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003263 try:
3264 # TODO: Maybe make this less hardcoded
3265 # ConsistentMap Exceptions
3266 assert "org.onosproject.store.service" not in output
3267 # Node not leader
3268 assert "java.lang.IllegalStateException" not in output
3269 except AssertionError:
3270 main.log.error( "Error in processing 'set-test-add' " +
3271 "command: " + str( output ) )
3272 retryTime = 30 # Conservative time, given by Madan
3273 main.log.info( "Waiting " + str( retryTime ) +
3274 "seconds before retrying." )
3275 time.sleep( retryTime ) # Due to change in mastership
3276 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003277 assert "Error executing command" not in output
3278 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3279 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3280 main.log.info( self.name + ": " + output )
3281 if re.search( positiveMatch, output):
3282 return main.TRUE
3283 elif re.search( negativeMatch, output):
3284 return main.FALSE
3285 else:
3286 main.log.error( self.name + ": setTestAdd did not" +
3287 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003288 main.log.debug( self.name + " actual: " + repr( output ) )
3289 return main.ERROR
3290 except AssertionError:
3291 main.log.error( "Error in processing 'set-test-add' command: " +
3292 str( output ) )
3293 return main.ERROR
3294 except TypeError:
3295 main.log.exception( self.name + ": Object not as expected" )
3296 return main.ERROR
3297 except pexpect.EOF:
3298 main.log.error( self.name + ": EOF exception found" )
3299 main.log.error( self.name + ": " + self.handle.before )
3300 main.cleanup()
3301 main.exit()
3302 except Exception:
3303 main.log.exception( self.name + ": Uncaught exception!" )
3304 main.cleanup()
3305 main.exit()
3306
3307 def setTestRemove( self, setName, values, clear=False, retain=False ):
3308 """
3309 CLI command to remove elements from a distributed set.
3310 Required arguments:
3311 setName - The name of the set to remove from.
3312 values - The value(s) to remove from the set, space seperated.
3313 Optional arguments:
3314 clear - Clear all elements from the set
3315 retain - Retain only the given values. (intersection of the
3316 original set and the given set)
3317 returns:
3318 main.TRUE on success OR
3319 main.FALSE if the set was not changed OR
3320 main.ERROR on error
3321 """
3322 try:
3323 cmdStr = "set-test-remove "
3324 if clear:
3325 cmdStr += "-c " + str( setName )
3326 elif retain:
3327 cmdStr += "-r " + str( setName ) + " " + str( values )
3328 else:
3329 cmdStr += str( setName ) + " " + str( values )
3330 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003331 try:
3332 # TODO: Maybe make this less hardcoded
3333 # ConsistentMap Exceptions
3334 assert "org.onosproject.store.service" not in output
3335 # Node not leader
3336 assert "java.lang.IllegalStateException" not in output
3337 except AssertionError:
3338 main.log.error( "Error in processing 'set-test-add' " +
3339 "command: " + str( output ) )
3340 retryTime = 30 # Conservative time, given by Madan
3341 main.log.info( "Waiting " + str( retryTime ) +
3342 "seconds before retrying." )
3343 time.sleep( retryTime ) # Due to change in mastership
3344 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003345 assert "Error executing command" not in output
3346 main.log.info( self.name + ": " + output )
3347 if clear:
3348 pattern = "Set " + str( setName ) + " cleared"
3349 if re.search( pattern, output ):
3350 return main.TRUE
3351 elif retain:
3352 positivePattern = str( setName ) + " was pruned to contain " +\
3353 "only elements of set \[(.*)\]"
3354 negativePattern = str( setName ) + " was not changed by " +\
3355 "retaining only elements of the set " +\
3356 "\[(.*)\]"
3357 if re.search( positivePattern, output ):
3358 return main.TRUE
3359 elif re.search( negativePattern, output ):
3360 return main.FALSE
3361 else:
3362 positivePattern = "\[(.*)\] was removed from the set " +\
3363 str( setName )
3364 if ( len( values.split() ) == 1 ):
3365 negativePattern = "\[(.*)\] was not in set " +\
3366 str( setName )
3367 else:
3368 negativePattern = "No element of \[(.*)\] was in set " +\
3369 str( setName )
3370 if re.search( positivePattern, output ):
3371 return main.TRUE
3372 elif re.search( negativePattern, output ):
3373 return main.FALSE
3374 main.log.error( self.name + ": setTestRemove did not" +
3375 " match expected output" )
3376 main.log.debug( self.name + " expected: " + pattern )
3377 main.log.debug( self.name + " actual: " + repr( output ) )
3378 return main.ERROR
3379 except AssertionError:
3380 main.log.error( "Error in processing 'set-test-remove' command: " +
3381 str( output ) )
3382 return main.ERROR
3383 except TypeError:
3384 main.log.exception( self.name + ": Object not as expected" )
3385 return main.ERROR
3386 except pexpect.EOF:
3387 main.log.error( self.name + ": EOF exception found" )
3388 main.log.error( self.name + ": " + self.handle.before )
3389 main.cleanup()
3390 main.exit()
3391 except Exception:
3392 main.log.exception( self.name + ": Uncaught exception!" )
3393 main.cleanup()
3394 main.exit()
3395
3396 def setTestGet( self, setName, values="" ):
3397 """
3398 CLI command to get the elements in a distributed set.
3399 Required arguments:
3400 setName - The name of the set to remove from.
3401 Optional arguments:
3402 values - The value(s) to check if in the set, space seperated.
3403 returns:
3404 main.ERROR on error OR
3405 A list of elements in the set if no optional arguments are
3406 supplied OR
3407 A tuple containing the list then:
3408 main.FALSE if the given values are not in the set OR
3409 main.TRUE if the given values are in the set OR
3410 """
3411 try:
3412 values = str( values ).strip()
3413 setName = str( setName ).strip()
3414 length = len( values.split() )
3415 containsCheck = None
3416 # Patterns to match
3417 setPattern = "\[(.*)\]"
3418 pattern = "Items in set " + setName + ":\n" + setPattern
3419 containsTrue = "Set " + setName + " contains the value " + values
3420 containsFalse = "Set " + setName + " did not contain the value " +\
3421 values
3422 containsAllTrue = "Set " + setName + " contains the the subset " +\
3423 setPattern
3424 containsAllFalse = "Set " + setName + " did not contain the the" +\
3425 " subset " + setPattern
3426
3427 cmdStr = "set-test-get "
3428 cmdStr += setName + " " + values
3429 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003430 try:
3431 # TODO: Maybe make this less hardcoded
3432 # ConsistentMap Exceptions
3433 assert "org.onosproject.store.service" not in output
3434 # Node not leader
3435 assert "java.lang.IllegalStateException" not in output
3436 except AssertionError:
3437 main.log.error( "Error in processing 'set-test-add' " +
3438 "command: " + str( output ) )
3439 retryTime = 30 # Conservative time, given by Madan
3440 main.log.info( "Waiting " + str( retryTime ) +
3441 "seconds before retrying." )
3442 time.sleep( retryTime ) # Due to change in mastership
3443 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003444 assert "Error executing command" not in output
3445 main.log.info( self.name + ": " + output )
3446
3447 if length == 0:
3448 match = re.search( pattern, output )
3449 else: # if given values
3450 if length == 1: # Contains output
3451 patternTrue = pattern + "\n" + containsTrue
3452 patternFalse = pattern + "\n" + containsFalse
3453 else: # ContainsAll output
3454 patternTrue = pattern + "\n" + containsAllTrue
3455 patternFalse = pattern + "\n" + containsAllFalse
3456 matchTrue = re.search( patternTrue, output )
3457 matchFalse = re.search( patternFalse, output )
3458 if matchTrue:
3459 containsCheck = main.TRUE
3460 match = matchTrue
3461 elif matchFalse:
3462 containsCheck = main.FALSE
3463 match = matchFalse
3464 else:
3465 main.log.error( self.name + " setTestGet did not match " +\
3466 "expected output" )
3467 main.log.debug( self.name + " expected: " + pattern )
3468 main.log.debug( self.name + " actual: " + repr( output ) )
3469 match = None
3470 if match:
3471 setMatch = match.group( 1 )
3472 if setMatch == '':
3473 setList = []
3474 else:
3475 setList = setMatch.split( ", " )
3476 if length > 0:
3477 return ( setList, containsCheck )
3478 else:
3479 return setList
3480 else: # no match
3481 main.log.error( self.name + ": setTestGet did not" +
3482 " match expected output" )
3483 main.log.debug( self.name + " expected: " + pattern )
3484 main.log.debug( self.name + " actual: " + repr( output ) )
3485 return main.ERROR
3486 except AssertionError:
3487 main.log.error( "Error in processing 'set-test-get' command: " +
3488 str( output ) )
3489 return main.ERROR
3490 except TypeError:
3491 main.log.exception( self.name + ": Object not as expected" )
3492 return main.ERROR
3493 except pexpect.EOF:
3494 main.log.error( self.name + ": EOF exception found" )
3495 main.log.error( self.name + ": " + self.handle.before )
3496 main.cleanup()
3497 main.exit()
3498 except Exception:
3499 main.log.exception( self.name + ": Uncaught exception!" )
3500 main.cleanup()
3501 main.exit()
3502
3503 def setTestSize( self, setName ):
3504 """
3505 CLI command to get the elements in a distributed set.
3506 Required arguments:
3507 setName - The name of the set to remove from.
3508 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003509 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003510 None on error
3511 """
3512 try:
3513 # TODO: Should this check against the number of elements returned
3514 # and then return true/false based on that?
3515 setName = str( setName ).strip()
3516 # Patterns to match
3517 setPattern = "\[(.*)\]"
3518 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3519 setPattern
3520 cmdStr = "set-test-get -s "
3521 cmdStr += setName
3522 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003523 try:
3524 # TODO: Maybe make this less hardcoded
3525 # ConsistentMap Exceptions
3526 assert "org.onosproject.store.service" not in output
3527 # Node not leader
3528 assert "java.lang.IllegalStateException" not in output
3529 except AssertionError:
3530 main.log.error( "Error in processing 'set-test-add' " +
3531 "command: " + str( output ) )
3532 retryTime = 30 # Conservative time, given by Madan
3533 main.log.info( "Waiting " + str( retryTime ) +
3534 "seconds before retrying." )
3535 time.sleep( retryTime ) # Due to change in mastership
3536 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003537 assert "Error executing command" not in output
3538 main.log.info( self.name + ": " + output )
3539 match = re.search( pattern, output )
3540 if match:
3541 setSize = int( match.group( 1 ) )
3542 setMatch = match.group( 2 )
3543 if len( setMatch.split() ) == setSize:
3544 main.log.info( "The size returned by " + self.name +
3545 " matches the number of elements in " +
3546 "the returned set" )
3547 else:
3548 main.log.error( "The size returned by " + self.name +
3549 " does not match the number of " +
3550 "elements in the returned set." )
3551 return setSize
3552 else: # no match
3553 main.log.error( self.name + ": setTestGet did not" +
3554 " match expected output" )
3555 main.log.debug( self.name + " expected: " + pattern )
3556 main.log.debug( self.name + " actual: " + repr( output ) )
3557 return None
3558 except AssertionError:
3559 main.log.error( "Error in processing 'set-test-get' command: " +
3560 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003561 return None
Jon Hall390696c2015-05-05 17:13:41 -07003562 except TypeError:
3563 main.log.exception( self.name + ": Object not as expected" )
3564 return None
3565 except pexpect.EOF:
3566 main.log.error( self.name + ": EOF exception found" )
3567 main.log.error( self.name + ": " + self.handle.before )
3568 main.cleanup()
3569 main.exit()
3570 except Exception:
3571 main.log.exception( self.name + ": Uncaught exception!" )
3572 main.cleanup()
3573 main.exit()
3574
Jon Hall80daded2015-05-27 16:07:00 -07003575 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003576 """
3577 Command to list the various counters in the system.
3578 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003579 if jsonFormat, a string of the json object returned by the cli
3580 command
3581 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003582 None on error
3583 """
Jon Hall390696c2015-05-05 17:13:41 -07003584 try:
3585 counters = {}
3586 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003587 if jsonFormat:
3588 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003589 output = self.sendline( cmdStr )
3590 assert "Error executing command" not in output
3591 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003592 return output
Jon Hall390696c2015-05-05 17:13:41 -07003593 except AssertionError:
3594 main.log.error( "Error in processing 'counters' command: " +
3595 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003596 return None
Jon Hall390696c2015-05-05 17:13:41 -07003597 except TypeError:
3598 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003599 return None
Jon Hall390696c2015-05-05 17:13:41 -07003600 except pexpect.EOF:
3601 main.log.error( self.name + ": EOF exception found" )
3602 main.log.error( self.name + ": " + self.handle.before )
3603 main.cleanup()
3604 main.exit()
3605 except Exception:
3606 main.log.exception( self.name + ": Uncaught exception!" )
3607 main.cleanup()
3608 main.exit()
3609
3610 def counterTestIncrement( self, counter, inMemory=False ):
3611 """
3612 CLI command to increment and get a distributed counter.
3613 Required arguments:
3614 counter - The name of the counter to increment.
3615 Optional arguments:
3616 inMemory - use in memory map for the counter
3617 returns:
3618 integer value of the counter or
3619 None on Error
3620 """
3621 try:
3622 counter = str( counter )
3623 cmdStr = "counter-test-increment "
3624 if inMemory:
3625 cmdStr += "-i "
3626 cmdStr += counter
3627 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003628 try:
3629 # TODO: Maybe make this less hardcoded
3630 # ConsistentMap Exceptions
3631 assert "org.onosproject.store.service" not in output
3632 # Node not leader
3633 assert "java.lang.IllegalStateException" not in output
3634 except AssertionError:
3635 main.log.error( "Error in processing 'set-test-add' " +
3636 "command: " + str( output ) )
3637 retryTime = 30 # Conservative time, given by Madan
3638 main.log.info( "Waiting " + str( retryTime ) +
3639 "seconds before retrying." )
3640 time.sleep( retryTime ) # Due to change in mastership
3641 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003642 assert "Error executing command" not in output
3643 main.log.info( self.name + ": " + output )
Jon Hallae734de2015-07-17 13:57:16 -07003644 pattern = counter + " was updated to (\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003645 match = re.search( pattern, output )
3646 if match:
3647 return int( match.group( 1 ) )
3648 else:
3649 main.log.error( self.name + ": counterTestIncrement did not" +
3650 " match expected output." )
3651 main.log.debug( self.name + " expected: " + pattern )
3652 main.log.debug( self.name + " actual: " + repr( output ) )
3653 return None
3654 except AssertionError:
3655 main.log.error( "Error in processing 'counter-test-increment'" +
3656 " command: " + str( output ) )
3657 return None
3658 except TypeError:
3659 main.log.exception( self.name + ": Object not as expected" )
3660 return None
3661 except pexpect.EOF:
3662 main.log.error( self.name + ": EOF exception found" )
3663 main.log.error( self.name + ": " + self.handle.before )
3664 main.cleanup()
3665 main.exit()
3666 except Exception:
3667 main.log.exception( self.name + ": Uncaught exception!" )
3668 main.cleanup()
3669 main.exit()
3670
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003671 def summary( self, jsonFormat=True ):
3672 """
3673 Description: Execute summary command in onos
3674 Returns: json object ( summary -j ), returns main.FALSE if there is
3675 no output
3676
3677 """
3678 try:
3679 cmdStr = "summary"
3680 if jsonFormat:
3681 cmdStr += " -j"
3682 handle = self.sendline( cmdStr )
3683
3684 if re.search( "Error:", handle ):
3685 main.log.error( self.name + ": summary() response: " +
3686 str( handle ) )
3687 if not handle:
3688 main.log.error( self.name + ": There is no output in " +
3689 "summary command" )
3690 return main.FALSE
3691 return handle
3692 except TypeError:
3693 main.log.exception( self.name + ": Object not as expected" )
3694 return None
3695 except pexpect.EOF:
3696 main.log.error( self.name + ": EOF exception found" )
3697 main.log.error( self.name + ": " + self.handle.before )
3698 main.cleanup()
3699 main.exit()
3700 except Exception:
3701 main.log.exception( self.name + ": Uncaught exception!" )
3702 main.cleanup()
3703 main.exit()