blob: e15ec407b009a9847b1cc759da8039d21737ec7f [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
GlennRC208d4af2015-11-24 12:30:00 -0800334 def sendline( self, cmdStr, showResponse=False, 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 ) )
GlennRC85870432015-11-23 11:45:51 -0800391 output = output[1].strip()
392 if showResponse:
393 main.log.info( "Resonse from ONOS: {}".format( output ) )
394 return output
Jon Hallc6358dd2015-04-10 12:44:28 -0700395 except IndexError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800398 except TypeError:
399 main.log.exception( self.name + ": Object not as expected" )
400 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400401 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800402 main.log.error( self.name + ": EOF exception found" )
403 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400404 main.cleanup()
405 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800406 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800407 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400408 main.cleanup()
409 main.exit()
410
kelvin8ec71442015-01-15 16:57:00 -0800411 # IMPORTANT NOTE:
412 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800413 # the cli command changing 'a:b' with 'aB'.
414 # Ex ) onos:topology > onosTopology
415 # onos:links > onosLinks
416 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800417
kelvin-onlabd3b64892015-01-20 13:26:24 -0800418 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800419 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400420 Adds a new cluster node by ID and address information.
421 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * nodeId
423 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400424 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800426 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400427 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800428 cmdStr = "add-node " + str( nodeId ) + " " +\
429 str( ONOSIp ) + " " + str( tcpPort )
430 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800431 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800432 main.log.error( "Error in adding node" )
433 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800434 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800436 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400437 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800438 except TypeError:
439 main.log.exception( self.name + ": Object not as expected" )
440 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800442 main.log.error( self.name + ": EOF exception found" )
443 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400444 main.cleanup()
445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800447 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400448 main.cleanup()
449 main.exit()
450
kelvin-onlabd3b64892015-01-20 13:26:24 -0800451 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800452 """
andrewonlab86dc3082014-10-13 18:18:38 -0400453 Removes a cluster by ID
454 Issues command: 'remove-node [<node-id>]'
455 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800457 """
andrewonlab86dc3082014-10-13 18:18:38 -0400458 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400459
kelvin-onlabd3b64892015-01-20 13:26:24 -0800460 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700461 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700462 if re.search( "Error", handle ):
463 main.log.error( "Error in removing node" )
464 main.log.error( handle )
465 return main.FALSE
466 else:
467 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800468 except TypeError:
469 main.log.exception( self.name + ": Object not as expected" )
470 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800472 main.log.error( self.name + ": EOF exception found" )
473 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400474 main.cleanup()
475 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800477 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400478 main.cleanup()
479 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400480
Jon Hall61282e32015-03-19 11:34:11 -0700481 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800482 """
andrewonlab7c211572014-10-15 16:45:20 -0400483 List the nodes currently visible
484 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700485 Optional argument:
486 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800487 """
andrewonlab7c211572014-10-15 16:45:20 -0400488 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700489 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700490 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700491 cmdStr += " -j"
492 output = self.sendline( cmdStr )
493 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800494 except TypeError:
495 main.log.exception( self.name + ": Object not as expected" )
496 return None
andrewonlab7c211572014-10-15 16:45:20 -0400497 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800498 main.log.error( self.name + ": EOF exception found" )
499 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400500 main.cleanup()
501 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800502 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800503 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400504 main.cleanup()
505 main.exit()
506
kelvin8ec71442015-01-15 16:57:00 -0800507 def topology( self ):
508 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700509 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700510 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700511 Return:
512 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800513 """
andrewonlab95ce8322014-10-13 14:12:04 -0400514 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700515 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800516 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400518 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800519 except TypeError:
520 main.log.exception( self.name + ": Object not as expected" )
521 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400522 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800523 main.log.error( self.name + ": EOF exception found" )
524 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400525 main.cleanup()
526 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800527 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800528 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400529 main.cleanup()
530 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800531
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800533 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 Installs a specified feature by issuing command:
535 'feature:install <feature_str>'
536 NOTE: This is now deprecated, you should use the activateApp method
537 instead
kelvin8ec71442015-01-15 16:57:00 -0800538 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400539 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800540 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700541 handle = self.sendline( cmdStr )
542 if re.search( "Error", handle ):
543 main.log.error( "Error in installing feature" )
544 main.log.error( handle )
545 return main.FALSE
546 else:
547 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800548 except TypeError:
549 main.log.exception( self.name + ": Object not as expected" )
550 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400551 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800552 main.log.error( self.name + ": EOF exception found" )
553 main.log.error( self.name + ": " + self.handle.before )
554 main.log.report( "Failed to install feature" )
555 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400556 main.cleanup()
557 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800558 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800559 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.report( "Failed to install feature" )
561 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400562 main.cleanup()
563 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800564
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800566 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700567 Uninstalls a specified feature by issuing command:
568 'feature:uninstall <feature_str>'
569 NOTE: This is now deprecated, you should use the deactivateApp method
570 instead
kelvin8ec71442015-01-15 16:57:00 -0800571 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800573 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
574 handle = self.sendline( cmdStr )
575 if handle != '':
576 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700577 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800578 # TODO: Check for possible error responses from karaf
579 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800580 main.log.info( "Feature needs to be installed before " +
581 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700582 return main.TRUE
583 if re.search( "Error", output ):
584 main.log.error( "Error in uninstalling feature" )
585 main.log.error( output )
586 return main.FALSE
587 else:
588 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800589 except TypeError:
590 main.log.exception( self.name + ": Object not as expected" )
591 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 main.cleanup()
596 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800598 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400599 main.cleanup()
600 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800601
jenkins7ead5a82015-03-13 10:28:21 -0700602 def deviceRemove( self, deviceId ):
603 """
604 Removes particular device from storage
605
606 TODO: refactor this function
607 """
608 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700609 cmdStr = "device-remove " + str( deviceId )
610 handle = self.sendline( cmdStr )
611 if re.search( "Error", handle ):
612 main.log.error( "Error in removing device" )
613 main.log.error( handle )
614 return main.FALSE
615 else:
616 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700617 except TypeError:
618 main.log.exception( self.name + ": Object not as expected" )
619 return None
620 except pexpect.EOF:
621 main.log.error( self.name + ": EOF exception found" )
622 main.log.error( self.name + ": " + self.handle.before )
623 main.cleanup()
624 main.exit()
625 except Exception:
626 main.log.exception( self.name + ": Uncaught exception!" )
627 main.cleanup()
628 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700629
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800631 """
Jon Hall7b02d952014-10-17 20:14:54 -0400632 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400633 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800634 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800635 """
andrewonlab86dc3082014-10-13 18:18:38 -0400636 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700637 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700639 cmdStr += " -j"
640 handle = self.sendline( cmdStr )
641 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800642 except TypeError:
643 main.log.exception( self.name + ": Object not as expected" )
644 return None
andrewonlab7c211572014-10-15 16:45:20 -0400645 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800646 main.log.error( self.name + ": EOF exception found" )
647 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400648 main.cleanup()
649 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400652 main.cleanup()
653 main.exit()
654
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800656 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800657 This balances the devices across all controllers
658 by issuing command: 'onos> onos:balance-masters'
659 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800660 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800661 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800662 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700663 handle = self.sendline( cmdStr )
664 if re.search( "Error", handle ):
665 main.log.error( "Error in balancing masters" )
666 main.log.error( handle )
667 return main.FALSE
668 else:
669 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800670 except TypeError:
671 main.log.exception( self.name + ": Object not as expected" )
672 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800673 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800674 main.log.error( self.name + ": EOF exception found" )
675 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800676 main.cleanup()
677 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800678 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800679 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800680 main.cleanup()
681 main.exit()
682
acsmars24950022015-07-30 18:00:43 -0700683 def checkMasters( self,jsonFormat=True ):
684 """
685 Returns the output of the masters command.
686 Optional argument:
687 * jsonFormat - boolean indicating if you want output in json
688 """
689 try:
690 cmdStr = "onos:masters"
691 if jsonFormat:
692 cmdStr += " -j"
693 output = self.sendline( cmdStr )
694 return output
695 except TypeError:
696 main.log.exception( self.name + ": Object not as expected" )
697 return None
698 except pexpect.EOF:
699 main.log.error( self.name + ": EOF exception found" )
700 main.log.error( self.name + ": " + self.handle.before )
701 main.cleanup()
702 main.exit()
703 except Exception:
704 main.log.exception( self.name + ": Uncaught exception!" )
705 main.cleanup()
706 main.exit()
707
708 def checkBalanceMasters( self,jsonFormat=True ):
709 """
710 Uses the master command to check that the devices' leadership
711 is evenly divided
712
713 Dependencies: checkMasters() and summary()
714
715 Returns main.True if the devices are balanced
716 Returns main.False if the devices are unbalanced
717 Exits on Exception
718 Returns None on TypeError
719 """
720 try:
721 totalDevices = json.loads( self.summary() )[ "devices" ]
722 totalOwnedDevices = 0
723 masters = json.loads( self.checkMasters() )
724 first = masters[ 0 ][ "size" ]
725 for master in masters:
726 totalOwnedDevices += master[ "size" ]
727 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
728 main.log.error( "Mastership not balanced" )
729 main.log.info( "\n" + self.checkMasters( False ) )
730 return main.FALSE
731 main.log.info( "Mastership balanced between " \
732 + str( len(masters) ) + " masters" )
733 return main.TRUE
734 except TypeError:
735 main.log.exception( self.name + ": Object not as expected" )
736 return None
737 except pexpect.EOF:
738 main.log.error( self.name + ": EOF exception found" )
739 main.log.error( self.name + ": " + self.handle.before )
740 main.cleanup()
741 main.exit()
742 except Exception:
743 main.log.exception( self.name + ": Uncaught exception!" )
744 main.cleanup()
745 main.exit()
746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800748 """
Jon Halle8217482014-10-17 13:49:14 -0400749 Lists all core links
750 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800751 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800752 """
Jon Halle8217482014-10-17 13:49:14 -0400753 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700754 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700756 cmdStr += " -j"
757 handle = self.sendline( cmdStr )
758 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800759 except TypeError:
760 main.log.exception( self.name + ": Object not as expected" )
761 return None
Jon Halle8217482014-10-17 13:49:14 -0400762 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800763 main.log.error( self.name + ": EOF exception found" )
764 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400765 main.cleanup()
766 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800767 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800768 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400769 main.cleanup()
770 main.exit()
771
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800773 """
Jon Halle8217482014-10-17 13:49:14 -0400774 Lists all ports
775 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800776 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800777 """
Jon Halle8217482014-10-17 13:49:14 -0400778 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800780 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr += " -j"
782 handle = self.sendline( cmdStr )
783 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
Jon Halle8217482014-10-17 13:49:14 -0400787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400790 main.cleanup()
791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400794 main.cleanup()
795 main.exit()
796
kelvin-onlabd3b64892015-01-20 13:26:24 -0800797 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800798 """
Jon Hall983a1702014-10-28 18:44:22 -0400799 Lists all devices and the controllers with roles assigned to them
800 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800802 """
andrewonlab7c211572014-10-15 16:45:20 -0400803 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700804 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 cmdStr += " -j"
807 handle = self.sendline( cmdStr )
808 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800809 except TypeError:
810 main.log.exception( self.name + ": Object not as expected" )
811 return None
Jon Hall983a1702014-10-28 18:44:22 -0400812 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800813 main.log.error( self.name + ": EOF exception found" )
814 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400815 main.cleanup()
816 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800817 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800818 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400819 main.cleanup()
820 main.exit()
821
kelvin-onlabd3b64892015-01-20 13:26:24 -0800822 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800823 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800824 Given the a string containing the json representation of the "roles"
825 cli command and a partial or whole device id, returns a json object
826 containing the roles output for the first device whose id contains
827 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400828
829 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800830 A dict of the role assignments for the given device or
831 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800832 """
Jon Hall983a1702014-10-28 18:44:22 -0400833 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800834 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400835 return None
836 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 rawRoles = self.roles()
838 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800839 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800841 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800842 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400843 return device
844 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800845 except TypeError:
846 main.log.exception( self.name + ": Object not as expected" )
847 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400848 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400851 main.cleanup()
852 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800853 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800854 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400855 main.cleanup()
856 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800857
kelvin-onlabd3b64892015-01-20 13:26:24 -0800858 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800859 """
Jon Hall94fd0472014-12-08 11:52:42 -0800860 Iterates through each device and checks if there is a master assigned
861 Returns: main.TRUE if each device has a master
862 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800863 """
Jon Hall94fd0472014-12-08 11:52:42 -0800864 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 rawRoles = self.roles()
866 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800867 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800869 # print device
870 if device[ 'master' ] == "none":
871 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800872 return main.FALSE
873 return main.TRUE
874
Jon Halld4d4b372015-01-28 16:02:41 -0800875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400890 Returns string of paths, and the cost.
891 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800892 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
895 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800896 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( "Error in getting paths" )
898 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400899 else:
kelvin8ec71442015-01-15 16:57:00 -0800900 path = handle.split( ";" )[ 0 ]
901 cost = handle.split( ";" )[ 1 ]
902 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800903 except TypeError:
904 main.log.exception( self.name + ": Object not as expected" )
905 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400906 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800907 main.log.error( self.name + ": EOF exception found" )
908 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400909 main.cleanup()
910 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800911 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800912 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400913 main.cleanup()
914 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800915
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800917 """
Jon Hallffb386d2014-11-21 13:43:38 -0800918 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400919 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800921 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400922 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700923 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700925 cmdStr += " -j"
926 handle = self.sendline( cmdStr )
Jon Hallbaf53162015-12-17 17:04:34 -0800927 try:
928 # TODO: Maybe make this less hardcoded
929 # ConsistentMap Exceptions
930 assert "org.onosproject.store.service" not in handle
931 # Node not leader
932 assert "java.lang.IllegalStateException" not in handle
933 except AssertionError:
934 main.log.error( "Error in processing '" + cmdStr + "' " +
935 "command: " + str( handle ) )
936 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800938 except TypeError:
939 main.log.exception( self.name + ": Object not as expected" )
940 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400944 main.cleanup()
945 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800946 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800947 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400948 main.cleanup()
949 main.exit()
950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800952 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800954
Jon Hallefbd9792015-03-05 16:11:36 -0800955 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800956 partial mac address
957
Jon Hall42db6dc2014-10-24 19:03:48 -0400958 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800959 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400960 try:
kelvin8ec71442015-01-15 16:57:00 -0800961 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400962 return None
963 else:
964 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 rawHosts = self.hosts()
966 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800967 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800969 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800970 if not host:
971 pass
972 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400973 return host
974 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800975 except TypeError:
976 main.log.exception( self.name + ": Object not as expected" )
977 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400981 main.cleanup()
982 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400985 main.cleanup()
986 main.exit()
987
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800989 """
990 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400991 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800992
andrewonlab3f0a4af2014-10-17 12:25:14 -0400993 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400995 IMPORTANT:
996 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800997 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 Furthermore, it assumes that value of VLAN is '-1'
999 Description:
kelvin8ec71442015-01-15 16:57:00 -08001000 Converts mininet hosts ( h1, h2, h3... ) into
1001 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1002 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001005
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001007 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 hostHex = hex( int( host ) ).zfill( 12 )
1009 hostHex = str( hostHex ).replace( 'x', '0' )
1010 i = iter( str( hostHex ) )
1011 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1012 hostHex = hostHex + "/-1"
1013 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001014
kelvin-onlabd3b64892015-01-20 13:26:24 -08001015 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001016
Jon Halld4d4b372015-01-28 16:02:41 -08001017 except TypeError:
1018 main.log.exception( self.name + ": Object not as expected" )
1019 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001023 main.cleanup()
1024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001026 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001027 main.cleanup()
1028 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001029
kelvin-onlabd3b64892015-01-20 13:26:24 -08001030 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlabe6745342014-10-17 14:29:13 -04001032 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * hostIdOne: ONOS host id for host1
1034 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001035 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001036 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001037 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001038 Returns:
1039 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001040 """
andrewonlabe6745342014-10-17 14:29:13 -04001041 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1043 " " + str( hostIdTwo )
1044 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -08001045 if re.search( "Error", handle ):
1046 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001047 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001048 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001049 else:
1050 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001051 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1052 match = re.search('id=0x([\da-f]+),', handle)
1053 if match:
1054 return match.group()[3:-1]
1055 else:
1056 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001057 main.log.debug( "Response from ONOS was: " +
1058 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001059 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001060 except TypeError:
1061 main.log.exception( self.name + ": Object not as expected" )
1062 return None
andrewonlabe6745342014-10-17 14:29:13 -04001063 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001064 main.log.error( self.name + ": EOF exception found" )
1065 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001066 main.cleanup()
1067 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001068 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001069 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001070 main.cleanup()
1071 main.exit()
1072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001074 """
andrewonlab7b31d232014-10-24 13:31:47 -04001075 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 * ingressDevice: device id of ingress device
1077 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001078 Optional:
1079 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001080 Description:
1081 Adds an optical intent by specifying an ingress and egress device
1082 Returns:
1083 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001084 """
andrewonlab7b31d232014-10-24 13:31:47 -04001085 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1087 " " + str( egressDevice )
1088 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001089 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001091 main.log.error( "Error in adding Optical intent" )
1092 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001093 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001094 main.log.info( "Optical intent installed between " +
1095 str( ingressDevice ) + " and " +
1096 str( egressDevice ) )
1097 match = re.search('id=0x([\da-f]+),', handle)
1098 if match:
1099 return match.group()[3:-1]
1100 else:
1101 main.log.error( "Error, intent ID not found" )
1102 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001103 except TypeError:
1104 main.log.exception( self.name + ": Object not as expected" )
1105 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001109 main.cleanup()
1110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001112 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001113 main.cleanup()
1114 main.exit()
1115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001117 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 ingressDevice,
1119 egressDevice,
1120 portIngress="",
1121 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001122 ethType="",
1123 ethSrc="",
1124 ethDst="",
1125 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001127 ipProto="",
1128 ipSrc="",
1129 ipDst="",
1130 tcpSrc="",
1131 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001132 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001133 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 * ingressDevice: device id of ingress device
1135 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001136 Optional:
1137 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001138 * ethSrc: specify ethSrc ( i.e. src mac addr )
1139 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001140 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001142 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001143 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001144 * ipSrc: specify ip source address
1145 * ipDst: specify ip destination address
1146 * tcpSrc: specify tcp source port
1147 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001148 Description:
kelvin8ec71442015-01-15 16:57:00 -08001149 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001150 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001151 Returns:
1152 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001153
Jon Halle3f39ff2015-01-13 11:50:53 -08001154 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001155 options developers provide for point-to-point
1156 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001157 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001158 try:
kelvin8ec71442015-01-15 16:57:00 -08001159 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001160 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001162 and not ipProto and not ipSrc and not ipDst \
1163 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001164 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001165
andrewonlab289e4b72014-10-21 21:24:18 -04001166 else:
andrewonlab36af3822014-11-18 17:48:18 -05001167 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001168
andrewonlab0c0a6772014-10-22 12:31:18 -04001169 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001170 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001171 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001172 cmd += " --ethSrc " + str( ethSrc )
1173 if ethDst:
1174 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001175 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001176 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001177 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001178 cmd += " --lambda "
1179 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001180 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001181 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001182 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001183 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001184 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001185 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001186 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001187 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001188 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001189
kelvin8ec71442015-01-15 16:57:00 -08001190 # Check whether the user appended the port
1191 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 if "/" in ingressDevice:
1193 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001194 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001197 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001198 # Would it make sense to throw an exception and exit
1199 # the test?
1200 return None
andrewonlab36af3822014-11-18 17:48:18 -05001201
kelvin8ec71442015-01-15 16:57:00 -08001202 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 str( ingressDevice ) + "/" +\
1204 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001205
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 if "/" in egressDevice:
1207 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001208 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001210 main.log.error( "You must specify the egress port" )
1211 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001212
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 str( egressDevice ) + "/" +\
1215 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001216
kelvin-onlab898a6c62015-01-16 14:13:53 -08001217 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001219 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001220 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001221 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001222 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001223 # TODO: print out all the options in this message?
1224 main.log.info( "Point-to-point intent installed between " +
1225 str( ingressDevice ) + " and " +
1226 str( egressDevice ) )
1227 match = re.search('id=0x([\da-f]+),', handle)
1228 if match:
1229 return match.group()[3:-1]
1230 else:
1231 main.log.error( "Error, intent ID not found" )
1232 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001233 except TypeError:
1234 main.log.exception( self.name + ": Object not as expected" )
1235 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001236 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001237 main.log.error( self.name + ": EOF exception found" )
1238 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001239 main.cleanup()
1240 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001241 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001242 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001243 main.cleanup()
1244 main.exit()
1245
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001247 self,
shahshreyac2f97072015-03-19 17:04:29 -07001248 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001250 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001251 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001252 ethType="",
1253 ethSrc="",
1254 ethDst="",
1255 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001257 ipProto="",
1258 ipSrc="",
1259 ipDst="",
1260 tcpSrc="",
1261 tcpDst="",
1262 setEthSrc="",
1263 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001264 """
shahshreyad0c80432014-12-04 16:56:05 -08001265 Note:
shahshreya70622b12015-03-19 17:19:00 -07001266 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001267 is same. That is, all ingress devices include port numbers
1268 with a "/" or all ingress devices could specify device
1269 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001270 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001271 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001272 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001274 Optional:
1275 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001276 * ethSrc: specify ethSrc ( i.e. src mac addr )
1277 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001278 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001280 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001281 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001282 * ipSrc: specify ip source address
1283 * ipDst: specify ip destination address
1284 * tcpSrc: specify tcp source port
1285 * tcpDst: specify tcp destination port
1286 * setEthSrc: action to Rewrite Source MAC Address
1287 * setEthDst: action to Rewrite Destination MAC Address
1288 Description:
kelvin8ec71442015-01-15 16:57:00 -08001289 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001290 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 Returns:
1292 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001293
Jon Halle3f39ff2015-01-13 11:50:53 -08001294 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001295 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001296 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001297 """
shahshreyad0c80432014-12-04 16:56:05 -08001298 try:
kelvin8ec71442015-01-15 16:57:00 -08001299 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001300 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001301 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 and not ipProto and not ipSrc and not ipDst\
1303 and not tcpSrc and not tcpDst and not setEthSrc\
1304 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001305 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001306
1307 else:
1308 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001309
shahshreyad0c80432014-12-04 16:56:05 -08001310 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001311 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001312 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001313 cmd += " --ethSrc " + str( ethSrc )
1314 if ethDst:
1315 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001316 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001317 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001319 cmd += " --lambda "
1320 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001321 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001322 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001323 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001324 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001325 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001326 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001327 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001328 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001329 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001330 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001331 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001332 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001333 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001334
kelvin8ec71442015-01-15 16:57:00 -08001335 # Check whether the user appended the port
1336 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001337
1338 if portIngressList is None:
1339 for ingressDevice in ingressDeviceList:
1340 if "/" in ingressDevice:
1341 cmd += " " + str( ingressDevice )
1342 else:
1343 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001344 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001345 # TODO: perhaps more meaningful return
1346 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001347 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001348 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001349 for ingressDevice, portIngress in zip( ingressDeviceList,
1350 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001351 cmd += " " + \
1352 str( ingressDevice ) + "/" +\
1353 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001354 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001355 main.log.error( "Device list and port list does not " +
1356 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001357 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 if "/" in egressDevice:
1359 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001360 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001362 main.log.error( "You must specify " +
1363 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001364 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001365
kelvin8ec71442015-01-15 16:57:00 -08001366 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 str( egressDevice ) + "/" +\
1368 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001371 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 main.log.error( "Error in adding multipoint-to-singlepoint " +
1373 "intent" )
1374 return None
shahshreyad0c80432014-12-04 16:56:05 -08001375 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001376 match = re.search('id=0x([\da-f]+),', handle)
1377 if match:
1378 return match.group()[3:-1]
1379 else:
1380 main.log.error( "Error, intent ID not found" )
1381 return None
1382 except TypeError:
1383 main.log.exception( self.name + ": Object not as expected" )
1384 return None
1385 except pexpect.EOF:
1386 main.log.error( self.name + ": EOF exception found" )
1387 main.log.error( self.name + ": " + self.handle.before )
1388 main.cleanup()
1389 main.exit()
1390 except Exception:
1391 main.log.exception( self.name + ": Uncaught exception!" )
1392 main.cleanup()
1393 main.exit()
1394
1395 def addSinglepointToMultipointIntent(
1396 self,
1397 ingressDevice,
1398 egressDeviceList,
1399 portIngress="",
1400 portEgressList=None,
1401 ethType="",
1402 ethSrc="",
1403 ethDst="",
1404 bandwidth="",
1405 lambdaAlloc=False,
1406 ipProto="",
1407 ipSrc="",
1408 ipDst="",
1409 tcpSrc="",
1410 tcpDst="",
1411 setEthSrc="",
1412 setEthDst="" ):
1413 """
1414 Note:
1415 This function assumes the format of all egress devices
1416 is same. That is, all egress devices include port numbers
1417 with a "/" or all egress devices could specify device
1418 ids and port numbers seperately.
1419 Required:
1420 * EgressDeviceList: List of device ids of egress device
1421 ( Atleast 2 eress devices required in the list )
1422 * ingressDevice: device id of ingress device
1423 Optional:
1424 * ethType: specify ethType
1425 * ethSrc: specify ethSrc ( i.e. src mac addr )
1426 * ethDst: specify ethDst ( i.e. dst mac addr )
1427 * bandwidth: specify bandwidth capacity of link
1428 * lambdaAlloc: if True, intent will allocate lambda
1429 for the specified intent
1430 * ipProto: specify ip protocol
1431 * ipSrc: specify ip source address
1432 * ipDst: specify ip destination address
1433 * tcpSrc: specify tcp source port
1434 * tcpDst: specify tcp destination port
1435 * setEthSrc: action to Rewrite Source MAC Address
1436 * setEthDst: action to Rewrite Destination MAC Address
1437 Description:
1438 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1439 specifying device id's and optional fields
1440 Returns:
1441 A string of the intent id or None on error
1442
1443 NOTE: This function may change depending on the
1444 options developers provide for singlepoint-to-multipoint
1445 intent via cli
1446 """
1447 try:
1448 # If there are no optional arguments
1449 if not ethType and not ethSrc and not ethDst\
1450 and not bandwidth and not lambdaAlloc\
1451 and not ipProto and not ipSrc and not ipDst\
1452 and not tcpSrc and not tcpDst and not setEthSrc\
1453 and not setEthDst:
1454 cmd = "add-single-to-multi-intent"
1455
1456 else:
1457 cmd = "add-single-to-multi-intent"
1458
1459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483
1484 # Check whether the user appended the port
1485 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001486
kelvin-onlabb9408212015-04-01 13:34:04 -07001487 if "/" in ingressDevice:
1488 cmd += " " + str( ingressDevice )
1489 else:
1490 if not portIngress:
1491 main.log.error( "You must specify " +
1492 "the Ingress port" )
1493 return main.FALSE
1494
1495 cmd += " " +\
1496 str( ingressDevice ) + "/" +\
1497 str( portIngress )
1498
1499 if portEgressList is None:
1500 for egressDevice in egressDeviceList:
1501 if "/" in egressDevice:
1502 cmd += " " + str( egressDevice )
1503 else:
1504 main.log.error( "You must specify " +
1505 "the egress port" )
1506 # TODO: perhaps more meaningful return
1507 return main.FALSE
1508 else:
1509 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001510 for egressDevice, portEgress in zip( egressDeviceList,
1511 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001512 cmd += " " + \
1513 str( egressDevice ) + "/" +\
1514 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001515 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001516 main.log.error( "Device list and port list does not " +
1517 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001518 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001519 handle = self.sendline( cmd )
1520 # If error, return error message
1521 if re.search( "Error", handle ):
1522 main.log.error( "Error in adding singlepoint-to-multipoint " +
1523 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001524 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001525 else:
1526 match = re.search('id=0x([\da-f]+),', handle)
1527 if match:
1528 return match.group()[3:-1]
1529 else:
1530 main.log.error( "Error, intent ID not found" )
1531 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001532 except TypeError:
1533 main.log.exception( self.name + ": Object not as expected" )
1534 return None
shahshreyad0c80432014-12-04 16:56:05 -08001535 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001536 main.log.error( self.name + ": EOF exception found" )
1537 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001538 main.cleanup()
1539 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001540 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001541 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001542 main.cleanup()
1543 main.exit()
1544
Hari Krishna9e232602015-04-13 17:29:08 -07001545 def addMplsIntent(
1546 self,
1547 ingressDevice,
1548 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001549 ingressPort="",
1550 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001551 ethType="",
1552 ethSrc="",
1553 ethDst="",
1554 bandwidth="",
1555 lambdaAlloc=False,
1556 ipProto="",
1557 ipSrc="",
1558 ipDst="",
1559 tcpSrc="",
1560 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001561 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001562 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001563 priority=""):
1564 """
1565 Required:
1566 * ingressDevice: device id of ingress device
1567 * egressDevice: device id of egress device
1568 Optional:
1569 * ethType: specify ethType
1570 * ethSrc: specify ethSrc ( i.e. src mac addr )
1571 * ethDst: specify ethDst ( i.e. dst mac addr )
1572 * bandwidth: specify bandwidth capacity of link
1573 * lambdaAlloc: if True, intent will allocate lambda
1574 for the specified intent
1575 * ipProto: specify ip protocol
1576 * ipSrc: specify ip source address
1577 * ipDst: specify ip destination address
1578 * tcpSrc: specify tcp source port
1579 * tcpDst: specify tcp destination port
1580 * ingressLabel: Ingress MPLS label
1581 * egressLabel: Egress MPLS label
1582 Description:
1583 Adds MPLS intent by
1584 specifying device id's and optional fields
1585 Returns:
1586 A string of the intent id or None on error
1587
1588 NOTE: This function may change depending on the
1589 options developers provide for MPLS
1590 intent via cli
1591 """
1592 try:
1593 # If there are no optional arguments
1594 if not ethType and not ethSrc and not ethDst\
1595 and not bandwidth and not lambdaAlloc \
1596 and not ipProto and not ipSrc and not ipDst \
1597 and not tcpSrc and not tcpDst and not ingressLabel \
1598 and not egressLabel:
1599 cmd = "add-mpls-intent"
1600
1601 else:
1602 cmd = "add-mpls-intent"
1603
1604 if ethType:
1605 cmd += " --ethType " + str( ethType )
1606 if ethSrc:
1607 cmd += " --ethSrc " + str( ethSrc )
1608 if ethDst:
1609 cmd += " --ethDst " + str( ethDst )
1610 if bandwidth:
1611 cmd += " --bandwidth " + str( bandwidth )
1612 if lambdaAlloc:
1613 cmd += " --lambda "
1614 if ipProto:
1615 cmd += " --ipProto " + str( ipProto )
1616 if ipSrc:
1617 cmd += " --ipSrc " + str( ipSrc )
1618 if ipDst:
1619 cmd += " --ipDst " + str( ipDst )
1620 if tcpSrc:
1621 cmd += " --tcpSrc " + str( tcpSrc )
1622 if tcpDst:
1623 cmd += " --tcpDst " + str( tcpDst )
1624 if ingressLabel:
1625 cmd += " --ingressLabel " + str( ingressLabel )
1626 if egressLabel:
1627 cmd += " --egressLabel " + str( egressLabel )
1628 if priority:
1629 cmd += " --priority " + str( priority )
1630
1631 # Check whether the user appended the port
1632 # or provided it as an input
1633 if "/" in ingressDevice:
1634 cmd += " " + str( ingressDevice )
1635 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001636 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001637 main.log.error( "You must specify the ingress port" )
1638 return None
1639
1640 cmd += " " + \
1641 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001642 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001643
1644 if "/" in egressDevice:
1645 cmd += " " + str( egressDevice )
1646 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001647 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001648 main.log.error( "You must specify the egress port" )
1649 return None
1650
1651 cmd += " " +\
1652 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001653 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001654
1655 handle = self.sendline( cmd )
1656 # If error, return error message
1657 if re.search( "Error", handle ):
1658 main.log.error( "Error in adding mpls intent" )
1659 return None
1660 else:
1661 # TODO: print out all the options in this message?
1662 main.log.info( "MPLS intent installed between " +
1663 str( ingressDevice ) + " and " +
1664 str( egressDevice ) )
1665 match = re.search('id=0x([\da-f]+),', handle)
1666 if match:
1667 return match.group()[3:-1]
1668 else:
1669 main.log.error( "Error, intent ID not found" )
1670 return None
1671 except TypeError:
1672 main.log.exception( self.name + ": Object not as expected" )
1673 return None
1674 except pexpect.EOF:
1675 main.log.error( self.name + ": EOF exception found" )
1676 main.log.error( self.name + ": " + self.handle.before )
1677 main.cleanup()
1678 main.exit()
1679 except Exception:
1680 main.log.exception( self.name + ": Uncaught exception!" )
1681 main.cleanup()
1682 main.exit()
1683
Jon Hallefbd9792015-03-05 16:11:36 -08001684 def removeIntent( self, intentId, app='org.onosproject.cli',
1685 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001686 """
shahshreya1c818fc2015-02-26 13:44:08 -08001687 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001688 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001689 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001690 -p or --purge: Purge the intent from the store after removal
1691
Jon Halle3f39ff2015-01-13 11:50:53 -08001692 Returns:
1693 main.False on error and
1694 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001695 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001696 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001697 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001698 if purge:
1699 cmdStr += " -p"
1700 if sync:
1701 cmdStr += " -s"
1702
1703 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001705 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001706 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001707 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001708 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001709 # TODO: Should this be main.TRUE
1710 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001711 except TypeError:
1712 main.log.exception( self.name + ": Object not as expected" )
1713 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001717 main.cleanup()
1718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001720 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001721 main.cleanup()
1722 main.exit()
1723
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001724 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001725 """
1726 Purges all WITHDRAWN Intents
1727 """
1728 try:
1729 cmdStr = "purge-intents"
1730 handle = self.sendline( cmdStr )
1731 if re.search( "Error", handle ):
1732 main.log.error( "Error in purging intents" )
1733 return main.FALSE
1734 else:
1735 return main.TRUE
1736 except TypeError:
1737 main.log.exception( self.name + ": Object not as expected" )
1738 return None
1739 except pexpect.EOF:
1740 main.log.error( self.name + ": EOF exception found" )
1741 main.log.error( self.name + ": " + self.handle.before )
1742 main.cleanup()
1743 main.exit()
1744 except Exception:
1745 main.log.exception( self.name + ": Uncaught exception!" )
1746 main.cleanup()
1747 main.exit()
1748
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001750 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001751 NOTE: This method should be used after installing application:
1752 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001753 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001754 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001755 Description:
1756 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001757 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001758 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001759 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001761 cmdStr += " -j"
1762 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001763 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001764 except TypeError:
1765 main.log.exception( self.name + ": Object not as expected" )
1766 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001768 main.log.error( self.name + ": EOF exception found" )
1769 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001770 main.cleanup()
1771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001773 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001774 main.cleanup()
1775 main.exit()
1776
pingping-lin54b03372015-08-13 14:43:10 -07001777 def ipv4RouteNumber( self ):
1778 """
1779 NOTE: This method should be used after installing application:
1780 onos-app-sdnip
1781 Description:
1782 Obtain the total IPv4 routes number in the system
1783 """
1784 try:
1785 cmdStr = "routes -s -j"
1786 handle = self.sendline( cmdStr )
1787 jsonResult = json.loads( handle )
1788 return jsonResult['totalRoutes4']
1789
1790 except TypeError:
1791 main.log.exception( self.name + ": Object not as expected" )
1792 return None
1793 except pexpect.EOF:
1794 main.log.error( self.name + ": EOF exception found" )
1795 main.log.error( self.name + ": " + self.handle.before )
1796 main.cleanup()
1797 main.exit()
1798 except Exception:
1799 main.log.exception( self.name + ": Uncaught exception!" )
1800 main.cleanup()
1801 main.exit()
1802
pingping-lin8244a3b2015-09-16 13:36:56 -07001803 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001804 """
andrewonlabe6745342014-10-17 14:29:13 -04001805 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001806 Obtain intents from the ONOS cli.
1807 Optional:
1808 * jsonFormat: Enable output formatting in json, default to True
1809 * summary: Whether only output the intent summary, defaults to False
1810 * type: Only output a certain type of intent. This options is valid
1811 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001812 """
andrewonlabe6745342014-10-17 14:29:13 -04001813 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001814 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001815 if summary:
1816 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001818 cmdStr += " -j"
1819 handle = self.sendline( cmdStr )
pingping-lin8244a3b2015-09-16 13:36:56 -07001820 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001821 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001822 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001823 else:
Jon Hallff566d52016-01-15 14:45:36 -08001824 intentType = ""
1825 # IF we want the summary of a specific intent type
1826 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001827 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001828 if intentType in jsonResult.keys():
1829 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001830 else:
Jon Hallff566d52016-01-15 14:45:36 -08001831 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001832 return handle
1833 else:
Jon Hallff566d52016-01-15 14:45:36 -08001834 main.log.error( handle )
pingping-lin8244a3b2015-09-16 13:36:56 -07001835 return handle
pingping-lin54b03372015-08-13 14:43:10 -07001836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
1842 main.cleanup()
1843 main.exit()
1844 except Exception:
1845 main.log.exception( self.name + ": Uncaught exception!" )
1846 main.cleanup()
1847 main.exit()
1848
kelvin-onlab54400a92015-02-26 18:05:51 -08001849 def getIntentState(self, intentsId, intentsJson=None):
1850 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001851 Check intent state.
1852 Accepts a single intent ID (string type) or a list of intent IDs.
1853 Returns the state(string type) of the id if a single intent ID is
1854 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001855 Returns a dictionary with intent IDs as the key and its
1856 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001857 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001858 intentId: intent ID (string type)
1859 intentsJson: parsed json object from the onos:intents api
1860 Returns:
1861 state = An intent's state- INSTALL,WITHDRAWN etc.
1862 stateDict = Dictionary of intent's state. intent ID as the keys and
1863 state as the values.
1864 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001865 try:
1866 state = "State is Undefined"
1867 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001868 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001869 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001870 intentsJsonTemp = json.loads( intentsJson )
1871 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001872 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001873 if intentsId == intent[ 'id' ]:
1874 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001875 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001876 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1877 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001878 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001879 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001880 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001881 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001882 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001883 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001884 if intentsId[ i ] == intents[ 'id' ]:
1885 stateDict[ 'state' ] = intents[ 'state' ]
1886 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001887 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001888 break
Jon Hallefbd9792015-03-05 16:11:36 -08001889 if len( intentsId ) != len( dictList ):
1890 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001891 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001892 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001893 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001894 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001895 except TypeError:
1896 main.log.exception( self.name + ": Object not as expected" )
1897 return None
1898 except pexpect.EOF:
1899 main.log.error( self.name + ": EOF exception found" )
1900 main.log.error( self.name + ": " + self.handle.before )
1901 main.cleanup()
1902 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001903 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001904 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001905 main.cleanup()
1906 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001907
kelvin-onlabf512e942015-06-08 19:42:59 -07001908 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001909 """
1910 Description:
1911 Check intents state
1912 Required:
1913 intentsId - List of intents ID to be checked
1914 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001915 expectedState - Check the expected state(s) of each intents
1916 state in the list.
1917 *NOTE: You can pass in a list of expected state,
1918 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001919 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001920 Returns main.TRUE only if all intent are the same as expected states
1921 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001922 """
1923 try:
1924 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001925 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001926 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001927
Jon Hall390696c2015-05-05 17:13:41 -07001928 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001929 if len( intentsId ) != len( intentsDict ):
1930 main.log.info( self.name + "There is something wrong " +
1931 "getting intents state" )
1932 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001933
1934 if isinstance( expectedState, types.StringType ):
1935 for intents in intentsDict:
1936 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001937 main.log.debug( self.name + " : Intent ID - " +
1938 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001939 " actual state = " +
1940 intents.get( 'state' )
1941 + " does not equal expected state = "
1942 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001943 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001944
1945 elif isinstance( expectedState, types.ListType ):
1946 for intents in intentsDict:
1947 if not any( state == intents.get( 'state' ) for state in
1948 expectedState ):
1949 main.log.debug( self.name + " : Intent ID - " +
1950 intents.get( 'id' ) +
1951 " actual state = " +
1952 intents.get( 'state' ) +
1953 " does not equal expected states = "
1954 + str( expectedState ) )
1955 returnValue = main.FALSE
1956
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001957 if returnValue == main.TRUE:
1958 main.log.info( self.name + ": All " +
1959 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001960 " intents are in " + str( expectedState ) +
1961 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001962 return returnValue
1963 except TypeError:
1964 main.log.exception( self.name + ": Object not as expected" )
1965 return None
1966 except pexpect.EOF:
1967 main.log.error( self.name + ": EOF exception found" )
1968 main.log.error( self.name + ": " + self.handle.before )
1969 main.cleanup()
1970 main.exit()
1971 except Exception:
1972 main.log.exception( self.name + ": Uncaught exception!" )
1973 main.cleanup()
1974 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04001975
kelvin-onlabd3b64892015-01-20 13:26:24 -08001976 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001977 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001978 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001979 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001980 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001981 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001982 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001983 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001984 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001985 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001986 cmdStr += " -j"
1987 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001988 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001989 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001990 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001991 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001992 except TypeError:
1993 main.log.exception( self.name + ": Object not as expected" )
1994 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001995 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001996 main.log.error( self.name + ": EOF exception found" )
1997 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001998 main.cleanup()
1999 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002000 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002001 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002002 main.cleanup()
2003 main.exit()
2004
pingping-linbab7f8a2015-09-21 17:33:36 -07002005 def checkFlowsState( self, isPENDING_ADD = True ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002006 """
2007 Description:
2008 Check the if all the current flows are in ADDED state or
2009 PENDING_ADD state
pingping-linbab7f8a2015-09-21 17:33:36 -07002010 Optional:
2011 * isPENDING_ADD: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002012 Return:
2013 returnValue - Returns main.TRUE only if all flows are in
pingping-linbab7f8a2015-09-21 17:33:36 -07002014 ADDED state or PENDING_ADD if the PENDING_ADD
2015 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002016 """
2017 try:
2018 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07002019 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07002020 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002021
pingping-linbab7f8a2015-09-21 17:33:36 -07002022 if isPENDING_ADD:
2023 for device in tempFlows:
2024 for flow in device.get( 'flows' ):
2025 if flow.get( 'state' ) != 'ADDED' and \
2026 flow.get( 'state' ) != 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002027
pingping-linbab7f8a2015-09-21 17:33:36 -07002028 main.log.info( self.name + ": flow Id: " +
2029 str( flow.get( 'groupId' ) ) +
2030 " | state:" +
2031 str( flow.get( 'state' ) ) )
2032 returnValue = main.FALSE
2033 else:
2034 for device in tempFlows:
2035 for flow in device.get( 'flows' ):
2036 if flow.get( 'state' ) != 'ADDED':
2037
2038 main.log.info( self.name + ": flow Id: " +
2039 str( flow.get( 'groupId' ) ) +
2040 " | state:" +
2041 str( flow.get( 'state' ) ) )
2042 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07002043
kelvin-onlab4df89f22015-04-13 18:10:23 -07002044 return returnValue
2045 except TypeError:
2046 main.log.exception( self.name + ": Object not as expected" )
2047 return None
2048 except pexpect.EOF:
2049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
2051 main.cleanup()
2052 main.exit()
2053 except Exception:
2054 main.log.exception( self.name + ": Uncaught exception!" )
2055 main.cleanup()
2056 main.exit()
2057
kelvin-onlabd3b64892015-01-20 13:26:24 -08002058 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08002059 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08002060 """
andrewonlab87852b02014-11-19 18:44:19 -05002061 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002062 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002063 a specific point-to-point intent definition
2064 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002065 * dpidSrc: specify source dpid
2066 * dpidDst: specify destination dpid
2067 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002068 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002069 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05002070 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08002071 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05002072 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05002073 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08002074 """
andrewonlab87852b02014-11-19 18:44:19 -05002075 try:
kelvin8ec71442015-01-15 16:57:00 -08002076 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08002077 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
2078 str( numIntents )
2079 if numMult:
2080 cmd += " " + str( numMult )
2081 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08002082 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08002083 if appId:
2084 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002085 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05002086 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002087 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08002088 main.log.info( handle )
2089 # Split result by newline
2090 newline = handle.split( "\r\r\n" )
2091 # Ignore the first object of list, which is empty
2092 newline = newline[ 1: ]
2093 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05002094 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08002095 result = result.split( ": " )
2096 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 latResult.append( result[ 1 ].split( " " )[ 0 ] )
2098 main.log.info( latResult )
2099 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05002100 else:
2101 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08002102 except TypeError:
2103 main.log.exception( self.name + ": Object not as expected" )
2104 return None
andrewonlab87852b02014-11-19 18:44:19 -05002105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002106 main.log.error( self.name + ": EOF exception found" )
2107 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002108 main.cleanup()
2109 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002111 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002112 main.cleanup()
2113 main.exit()
2114
kelvin-onlabd3b64892015-01-20 13:26:24 -08002115 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002116 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002117 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002118 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002119 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002120 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002121 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002122 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002123 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002124 cmdStr += " -j"
2125 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002126 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002127 except TypeError:
2128 main.log.exception( self.name + ": Object not as expected" )
2129 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002130 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 )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002133 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!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002137 main.cleanup()
2138 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002139
kelvin-onlabd3b64892015-01-20 13:26:24 -08002140 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002141 """
2142 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002143 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002144 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002145 """
andrewonlab867212a2014-10-22 20:13:38 -04002146 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002147 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002148 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002149 cmdStr += " -j"
2150 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002151 if handle:
2152 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002153 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002154 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002155 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002156 else:
2157 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002158 except TypeError:
2159 main.log.exception( self.name + ": Object not as expected" )
2160 return None
andrewonlab867212a2014-10-22 20:13:38 -04002161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002162 main.log.error( self.name + ": EOF exception found" )
2163 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002164 main.cleanup()
2165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002167 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002168 main.cleanup()
2169 main.exit()
2170
kelvin8ec71442015-01-15 16:57:00 -08002171 # Wrapper functions ****************
2172 # Wrapper functions use existing driver
2173 # functions and extends their use case.
2174 # For example, we may use the output of
2175 # a normal driver function, and parse it
2176 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002177
kelvin-onlabd3b64892015-01-20 13:26:24 -08002178 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002179 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002180 Description:
2181 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002182 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002183 try:
kelvin8ec71442015-01-15 16:57:00 -08002184 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002185 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002186 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002187
kelvin8ec71442015-01-15 16:57:00 -08002188 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002189 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2190 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002191 match = re.search('id=0x([\da-f]+),', intents)
2192 if match:
2193 tmpId = match.group()[3:-1]
2194 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002196
Jon Halld4d4b372015-01-28 16:02:41 -08002197 except TypeError:
2198 main.log.exception( self.name + ": Object not as expected" )
2199 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002200 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002201 main.log.error( self.name + ": EOF exception found" )
2202 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002203 main.cleanup()
2204 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002205 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002206 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002207 main.cleanup()
2208 main.exit()
2209
Jon Hall30b82fa2015-03-04 17:15:43 -08002210 def FlowAddedCount( self, deviceId ):
2211 """
2212 Determine the number of flow rules for the given device id that are
2213 in the added state
2214 """
2215 try:
2216 cmdStr = "flows any " + str( deviceId ) + " | " +\
2217 "grep 'state=ADDED' | wc -l"
2218 handle = self.sendline( cmdStr )
2219 return handle
2220 except pexpect.EOF:
2221 main.log.error( self.name + ": EOF exception found" )
2222 main.log.error( self.name + ": " + self.handle.before )
2223 main.cleanup()
2224 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002225 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002226 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002227 main.cleanup()
2228 main.exit()
2229
kelvin-onlabd3b64892015-01-20 13:26:24 -08002230 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002231 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002232 Use 'devices' function to obtain list of all devices
2233 and parse the result to obtain a list of all device
2234 id's. Returns this list. Returns empty list if no
2235 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002236 List is ordered sequentially
2237
andrewonlab3e15ead2014-10-15 14:21:34 -04002238 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002239 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002240 the ids. By obtaining the list of device ids on the fly,
2241 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002242 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002243 try:
kelvin8ec71442015-01-15 16:57:00 -08002244 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002245 devicesStr = self.devices( jsonFormat=False )
2246 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002247
kelvin-onlabd3b64892015-01-20 13:26:24 -08002248 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002249 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002250 return idList
kelvin8ec71442015-01-15 16:57:00 -08002251
2252 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002253 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002254 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002255 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002256 # Split list further into arguments before and after string
2257 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002258 # append to idList
2259 for arg in tempList:
2260 idList.append( arg.split( "id=" )[ 1 ] )
2261 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002262
Jon Halld4d4b372015-01-28 16:02:41 -08002263 except TypeError:
2264 main.log.exception( self.name + ": Object not as expected" )
2265 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002267 main.log.error( self.name + ": EOF exception found" )
2268 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002269 main.cleanup()
2270 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002271 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002272 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002273 main.cleanup()
2274 main.exit()
2275
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002277 """
andrewonlab7c211572014-10-15 16:45:20 -04002278 Uses 'nodes' function to obtain list of all nodes
2279 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002280 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002281 Returns:
2282 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002283 """
andrewonlab7c211572014-10-15 16:45:20 -04002284 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002285 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002286 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002287 # Sample nodesStr output
2288 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002290 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002292 nodesJson = json.loads( nodesStr )
2293 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002294 return idList
kelvin8ec71442015-01-15 16:57:00 -08002295
Jon Halld4d4b372015-01-28 16:02:41 -08002296 except TypeError:
2297 main.log.exception( self.name + ": Object not as expected" )
2298 return None
andrewonlab7c211572014-10-15 16:45:20 -04002299 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002300 main.log.error( self.name + ": EOF exception found" )
2301 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002302 main.cleanup()
2303 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002304 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002305 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002306 main.cleanup()
2307 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002308
kelvin-onlabd3b64892015-01-20 13:26:24 -08002309 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002310 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002311 Return the first device from the devices api whose 'id' contains 'dpid'
2312 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002313 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002314 try:
kelvin8ec71442015-01-15 16:57:00 -08002315 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002316 return None
2317 else:
kelvin8ec71442015-01-15 16:57:00 -08002318 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002319 rawDevices = self.devices()
2320 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002321 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002323 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2324 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002325 return device
2326 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002327 except TypeError:
2328 main.log.exception( self.name + ": Object not as expected" )
2329 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002331 main.log.error( self.name + ": EOF exception found" )
2332 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002333 main.cleanup()
2334 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002335 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002336 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002337 main.cleanup()
2338 main.exit()
2339
kelvin-onlabd3b64892015-01-20 13:26:24 -08002340 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002341 """
Jon Hallefbd9792015-03-05 16:11:36 -08002342 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002343 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002344 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002345
Jon Hall42db6dc2014-10-24 19:03:48 -04002346 Params: ip = ip used for the onos cli
2347 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002348 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002349 logLevel = level to log to. Currently accepts
2350 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002351
2352
kelvin-onlabd3b64892015-01-20 13:26:24 -08002353 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002354
Jon Hallefbd9792015-03-05 16:11:36 -08002355 Returns: main.TRUE if the number of switches and links are correct,
2356 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002357 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002358 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002359 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002360 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002361 if topology == {}:
2362 return main.ERROR
2363 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002364 # Is the number of switches is what we expected
2365 devices = topology.get( 'devices', False )
2366 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002367 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002368 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002369 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002370 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002371 linkCheck = ( int( links ) == int( numolink ) )
2372 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002373 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002374 output += "The number of links and switches match " +\
2375 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002376 result = main.TRUE
2377 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002378 output += "The number of links and switches does not match " +\
2379 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002380 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002381 output = output + "\n ONOS sees %i devices (%i expected) \
2382 and %i links (%i expected)" % (
2383 int( devices ), int( numoswitch ), int( links ),
2384 int( numolink ) )
2385 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002386 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002387 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002388 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002389 else:
Jon Hall390696c2015-05-05 17:13:41 -07002390 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002391 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002392 except TypeError:
2393 main.log.exception( self.name + ": Object not as expected" )
2394 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002395 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002396 main.log.error( self.name + ": EOF exception found" )
2397 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002398 main.cleanup()
2399 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002400 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002401 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002402 main.cleanup()
2403 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002404
kelvin-onlabd3b64892015-01-20 13:26:24 -08002405 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002406 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002407 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002408 deviceId must be the id of a device as seen in the onos devices command
2409 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002410 role must be either master, standby, or none
2411
Jon Halle3f39ff2015-01-13 11:50:53 -08002412 Returns:
2413 main.TRUE or main.FALSE based on argument verification and
2414 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002415 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002416 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002417 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002418 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002419 cmdStr = "device-role " +\
2420 str( deviceId ) + " " +\
2421 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002422 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002423 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002424 if re.search( "Error", handle ):
2425 # end color output to escape any colours
2426 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002427 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002428 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002429 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002430 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002431 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002432 main.log.error( "Invalid 'role' given to device_role(). " +
2433 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002434 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002435 except TypeError:
2436 main.log.exception( self.name + ": Object not as expected" )
2437 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002439 main.log.error( self.name + ": EOF exception found" )
2440 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002441 main.cleanup()
2442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002444 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002445 main.cleanup()
2446 main.exit()
2447
kelvin-onlabd3b64892015-01-20 13:26:24 -08002448 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002449 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002450 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002451 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002452 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002453 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002454 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002455 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002456 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002457 cmdStr += " -j"
2458 handle = self.sendline( cmdStr )
2459 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002460 except TypeError:
2461 main.log.exception( self.name + ": Object not as expected" )
2462 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002464 main.log.error( self.name + ": EOF exception found" )
2465 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002466 main.cleanup()
2467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002468 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002469 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002470 main.cleanup()
2471 main.exit()
2472
kelvin-onlabd3b64892015-01-20 13:26:24 -08002473 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002474 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002475 CLI command to get the current leader for the Election test application
2476 NOTE: Requires installation of the onos-app-election feature
2477 Returns: Node IP of the leader if one exists
2478 None if none exists
2479 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002480 """
Jon Hall94fd0472014-12-08 11:52:42 -08002481 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002482 cmdStr = "election-test-leader"
2483 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002484 # Leader
2485 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002486 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002487 nodeSearch = re.search( leaderPattern, response )
2488 if nodeSearch:
2489 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002490 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002491 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002492 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002493 # no leader
2494 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002495 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002496 nullSearch = re.search( nullPattern, response )
2497 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002498 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002499 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002500 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002501 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002502 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002503 if re.search( errorPattern, response ):
2504 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002505 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002506 return main.FALSE
2507 else:
Jon Hall390696c2015-05-05 17:13:41 -07002508 main.log.error( "Error in electionTestLeader on " + self.name +
2509 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002510 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002511 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002512 except TypeError:
2513 main.log.exception( self.name + ": Object not as expected" )
2514 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002516 main.log.error( self.name + ": EOF exception found" )
2517 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002518 main.cleanup()
2519 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002520 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002521 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002522 main.cleanup()
2523 main.exit()
2524
kelvin-onlabd3b64892015-01-20 13:26:24 -08002525 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002526 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002527 CLI command to run for leadership of the Election test application.
2528 NOTE: Requires installation of the onos-app-election feature
2529 Returns: Main.TRUE on success
2530 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002531 """
Jon Hall94fd0472014-12-08 11:52:42 -08002532 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002533 cmdStr = "election-test-run"
2534 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002535 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002536 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002537 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002538 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002539 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002540 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002541 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002542 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002543 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002544 errorPattern = "Command\snot\sfound"
2545 if re.search( errorPattern, response ):
2546 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002547 return main.FALSE
2548 else:
Jon Hall390696c2015-05-05 17:13:41 -07002549 main.log.error( "Error in electionTestRun on " + self.name +
2550 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002551 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002552 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002553 except TypeError:
2554 main.log.exception( self.name + ": Object not as expected" )
2555 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002557 main.log.error( self.name + ": EOF exception found" )
2558 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002559 main.cleanup()
2560 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002561 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002562 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002563 main.cleanup()
2564 main.exit()
2565
kelvin-onlabd3b64892015-01-20 13:26:24 -08002566 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002567 """
Jon Hall94fd0472014-12-08 11:52:42 -08002568 * CLI command to withdraw the local node from leadership election for
2569 * the Election test application.
2570 #NOTE: Requires installation of the onos-app-election feature
2571 Returns: Main.TRUE on success
2572 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002573 """
Jon Hall94fd0472014-12-08 11:52:42 -08002574 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002575 cmdStr = "election-test-withdraw"
2576 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002577 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002578 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002579 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002580 if re.search( successPattern, response ):
2581 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002582 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002583 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002584 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002585 errorPattern = "Command\snot\sfound"
2586 if re.search( errorPattern, response ):
2587 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002588 return main.FALSE
2589 else:
Jon Hall390696c2015-05-05 17:13:41 -07002590 main.log.error( "Error in electionTestWithdraw on " +
2591 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002592 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002593 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002594 except TypeError:
2595 main.log.exception( self.name + ": Object not as expected" )
2596 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002597 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002598 main.log.error( self.name + ": EOF exception found" )
2599 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002600 main.cleanup()
2601 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002602 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002603 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002604 main.cleanup()
2605 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002606
kelvin8ec71442015-01-15 16:57:00 -08002607 def getDevicePortsEnabledCount( self, dpid ):
2608 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002609 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002610 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002611 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002612 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002613 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2614 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002615 if re.search( "No such device", output ):
2616 main.log.error( "Error in getting ports" )
2617 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002618 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002619 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002620 except TypeError:
2621 main.log.exception( self.name + ": Object not as expected" )
2622 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002623 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002624 main.log.error( self.name + ": EOF exception found" )
2625 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002626 main.cleanup()
2627 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002628 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002629 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002630 main.cleanup()
2631 main.exit()
2632
kelvin8ec71442015-01-15 16:57:00 -08002633 def getDeviceLinksActiveCount( self, dpid ):
2634 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002635 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002636 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002637 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002638 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002639 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2640 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002641 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002642 main.log.error( "Error in getting ports " )
2643 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002644 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002645 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002646 except TypeError:
2647 main.log.exception( self.name + ": Object not as expected" )
2648 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002649 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002650 main.log.error( self.name + ": EOF exception found" )
2651 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002652 main.cleanup()
2653 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002654 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002655 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002656 main.cleanup()
2657 main.exit()
2658
kelvin8ec71442015-01-15 16:57:00 -08002659 def getAllIntentIds( self ):
2660 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002661 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002662 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002663 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 cmdStr = "onos:intents | grep id="
2665 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002666 if re.search( "Error", output ):
2667 main.log.error( "Error in getting ports" )
2668 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002669 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002670 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002671 except TypeError:
2672 main.log.exception( self.name + ": Object not as expected" )
2673 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002675 main.log.error( self.name + ": EOF exception found" )
2676 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002677 main.cleanup()
2678 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002679 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002680 main.log.exception( self.name + ": Uncaught exception!" )
2681 main.cleanup()
2682 main.exit()
2683
Jon Hall73509952015-02-24 16:42:56 -08002684 def intentSummary( self ):
2685 """
Jon Hallefbd9792015-03-05 16:11:36 -08002686 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002687 """
2688 try:
2689 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002690 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002691 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002692 states.append( intent.get( 'state', None ) )
2693 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002694 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002695 return dict( out )
2696 except TypeError:
2697 main.log.exception( self.name + ": Object not as expected" )
2698 return None
2699 except pexpect.EOF:
2700 main.log.error( self.name + ": EOF exception found" )
2701 main.log.error( self.name + ": " + self.handle.before )
2702 main.cleanup()
2703 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002704 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002705 main.log.exception( self.name + ": Uncaught exception!" )
2706 main.cleanup()
2707 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002708
Jon Hall61282e32015-03-19 11:34:11 -07002709 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002710 """
2711 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002712 Optional argument:
2713 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002714 """
Jon Hall63604932015-02-26 17:09:50 -08002715 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002716 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002717 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002718 cmdStr += " -j"
2719 output = self.sendline( cmdStr )
2720 return output
Jon Hall63604932015-02-26 17:09:50 -08002721 except TypeError:
2722 main.log.exception( self.name + ": Object not as expected" )
2723 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002724 except pexpect.EOF:
2725 main.log.error( self.name + ": EOF exception found" )
2726 main.log.error( self.name + ": " + self.handle.before )
2727 main.cleanup()
2728 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002729 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002730 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002731 main.cleanup()
2732 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002733
acsmarsa4a4d1e2015-07-10 16:01:24 -07002734 def leaderCandidates( self, jsonFormat=True ):
2735 """
2736 Returns the output of the leaders -c command.
2737 Optional argument:
2738 * jsonFormat - boolean indicating if you want output in json
2739 """
2740 try:
2741 cmdStr = "onos:leaders -c"
2742 if jsonFormat:
2743 cmdStr += " -j"
2744 output = self.sendline( cmdStr )
2745 return output
2746 except TypeError:
2747 main.log.exception( self.name + ": Object not as expected" )
2748 return None
2749 except pexpect.EOF:
2750 main.log.error( self.name + ": EOF exception found" )
2751 main.log.error( self.name + ": " + self.handle.before )
2752 main.cleanup()
2753 main.exit()
2754 except Exception:
2755 main.log.exception( self.name + ": Uncaught exception!" )
2756 main.cleanup()
2757 main.exit()
2758
2759 def specificLeaderCandidate(self,topic):
2760 """
2761 Returns a list in format [leader,candidate1,candidate2,...] for a given
2762 topic parameter and an empty list if the topic doesn't exist
2763 If no leader is elected leader in the returned list will be "none"
2764 Returns None if there is a type error processing the json object
2765 """
2766 try:
2767 cmdStr = "onos:leaders -c -j"
2768 output = self.sendline( cmdStr )
2769 output = json.loads(output)
2770 results = []
2771 for dict in output:
2772 if dict["topic"] == topic:
2773 leader = dict["leader"]
2774 candidates = re.split(", ",dict["candidates"][1:-1])
2775 results.append(leader)
2776 results.extend(candidates)
2777 return results
2778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return None
2781 except pexpect.EOF:
2782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
2784 main.cleanup()
2785 main.exit()
2786 except Exception:
2787 main.log.exception( self.name + ": Uncaught exception!" )
2788 main.cleanup()
2789 main.exit()
2790
Jon Hall61282e32015-03-19 11:34:11 -07002791 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002792 """
2793 Returns the output of the intent Pending map.
2794 """
Jon Hall63604932015-02-26 17:09:50 -08002795 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002796 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002797 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002798 cmdStr += " -j"
2799 output = self.sendline( cmdStr )
2800 return output
Jon Hall63604932015-02-26 17:09:50 -08002801 except TypeError:
2802 main.log.exception( self.name + ": Object not as expected" )
2803 return None
2804 except pexpect.EOF:
2805 main.log.error( self.name + ": EOF exception found" )
2806 main.log.error( self.name + ": " + self.handle.before )
2807 main.cleanup()
2808 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002809 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002810 main.log.exception( self.name + ": Uncaught exception!" )
2811 main.cleanup()
2812 main.exit()
2813
Jon Hall61282e32015-03-19 11:34:11 -07002814 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002815 """
2816 Returns the output of the raft partitions command for ONOS.
2817 """
Jon Hall61282e32015-03-19 11:34:11 -07002818 # Sample JSON
2819 # {
2820 # "leader": "tcp://10.128.30.11:7238",
2821 # "members": [
2822 # "tcp://10.128.30.11:7238",
2823 # "tcp://10.128.30.17:7238",
2824 # "tcp://10.128.30.13:7238",
2825 # ],
2826 # "name": "p1",
2827 # "term": 3
2828 # },
Jon Hall63604932015-02-26 17:09:50 -08002829 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002830 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002831 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002832 cmdStr += " -j"
2833 output = self.sendline( cmdStr )
2834 return output
Jon Hall63604932015-02-26 17:09:50 -08002835 except TypeError:
2836 main.log.exception( self.name + ": Object not as expected" )
2837 return None
2838 except pexpect.EOF:
2839 main.log.error( self.name + ": EOF exception found" )
2840 main.log.error( self.name + ": " + self.handle.before )
2841 main.cleanup()
2842 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002843 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002844 main.log.exception( self.name + ": Uncaught exception!" )
2845 main.cleanup()
2846 main.exit()
2847
Jon Hallbe379602015-03-24 13:39:32 -07002848 def apps( self, jsonFormat=True ):
2849 """
2850 Returns the output of the apps command for ONOS. This command lists
2851 information about installed ONOS applications
2852 """
2853 # Sample JSON object
2854 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2855 # "description":"ONOS OpenFlow protocol southbound providers",
2856 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2857 # "features":"[onos-openflow]","state":"ACTIVE"}]
2858 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002859 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002860 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002861 cmdStr += " -j"
2862 output = self.sendline( cmdStr )
2863 assert "Error executing command" not in output
2864 return output
Jon Hallbe379602015-03-24 13:39:32 -07002865 # FIXME: look at specific exceptions/Errors
2866 except AssertionError:
2867 main.log.error( "Error in processing onos:app command: " +
2868 str( output ) )
2869 return None
2870 except TypeError:
2871 main.log.exception( self.name + ": Object not as expected" )
2872 return None
2873 except pexpect.EOF:
2874 main.log.error( self.name + ": EOF exception found" )
2875 main.log.error( self.name + ": " + self.handle.before )
2876 main.cleanup()
2877 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002878 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002879 main.log.exception( self.name + ": Uncaught exception!" )
2880 main.cleanup()
2881 main.exit()
2882
Jon Hall146f1522015-03-24 15:33:24 -07002883 def appStatus( self, appName ):
2884 """
2885 Uses the onos:apps cli command to return the status of an application.
2886 Returns:
2887 "ACTIVE" - If app is installed and activated
2888 "INSTALLED" - If app is installed and deactivated
2889 "UNINSTALLED" - If app is not installed
2890 None - on error
2891 """
Jon Hall146f1522015-03-24 15:33:24 -07002892 try:
2893 if not isinstance( appName, types.StringType ):
2894 main.log.error( self.name + ".appStatus(): appName must be" +
2895 " a string" )
2896 return None
2897 output = self.apps( jsonFormat=True )
2898 appsJson = json.loads( output )
2899 state = None
2900 for app in appsJson:
2901 if appName == app.get('name'):
2902 state = app.get('state')
2903 break
2904 if state == "ACTIVE" or state == "INSTALLED":
2905 return state
2906 elif state is None:
2907 return "UNINSTALLED"
2908 elif state:
2909 main.log.error( "Unexpected state from 'onos:apps': " +
2910 str( state ) )
2911 return state
2912 except TypeError:
2913 main.log.exception( self.name + ": Object not as expected" )
2914 return None
2915 except pexpect.EOF:
2916 main.log.error( self.name + ": EOF exception found" )
2917 main.log.error( self.name + ": " + self.handle.before )
2918 main.cleanup()
2919 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002920 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002921 main.log.exception( self.name + ": Uncaught exception!" )
2922 main.cleanup()
2923 main.exit()
2924
Jon Hallbe379602015-03-24 13:39:32 -07002925 def app( self, appName, option ):
2926 """
2927 Interacts with the app command for ONOS. This command manages
2928 application inventory.
2929 """
Jon Hallbe379602015-03-24 13:39:32 -07002930 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002931 # Validate argument types
2932 valid = True
2933 if not isinstance( appName, types.StringType ):
2934 main.log.error( self.name + ".app(): appName must be a " +
2935 "string" )
2936 valid = False
2937 if not isinstance( option, types.StringType ):
2938 main.log.error( self.name + ".app(): option must be a string" )
2939 valid = False
2940 if not valid:
2941 return main.FALSE
2942 # Validate Option
2943 option = option.lower()
2944 # NOTE: Install may become a valid option
2945 if option == "activate":
2946 pass
2947 elif option == "deactivate":
2948 pass
2949 elif option == "uninstall":
2950 pass
2951 else:
2952 # Invalid option
2953 main.log.error( "The ONOS app command argument only takes " +
2954 "the values: (activate|deactivate|uninstall)" +
2955 "; was given '" + option + "'")
2956 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002957 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002958 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002959 if "Error executing command" in output:
2960 main.log.error( "Error in processing onos:app command: " +
2961 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002962 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002963 elif "No such application" in output:
2964 main.log.error( "The application '" + appName +
2965 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002966 return main.FALSE
2967 elif "Command not found:" in output:
2968 main.log.error( "Error in processing onos:app command: " +
2969 str( output ) )
2970 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002971 elif "Unsupported command:" in output:
2972 main.log.error( "Incorrect command given to 'app': " +
2973 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002974 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002975 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002976 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002977 return main.TRUE
2978 except TypeError:
2979 main.log.exception( self.name + ": Object not as expected" )
2980 return main.ERROR
2981 except pexpect.EOF:
2982 main.log.error( self.name + ": EOF exception found" )
2983 main.log.error( self.name + ": " + self.handle.before )
2984 main.cleanup()
2985 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002986 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002987 main.log.exception( self.name + ": Uncaught exception!" )
2988 main.cleanup()
2989 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002990
Jon Hallbd16b922015-03-26 17:53:15 -07002991 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002992 """
2993 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002994 appName is the hierarchical app name, not the feature name
2995 If check is True, method will check the status of the app after the
2996 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002997 Returns main.TRUE if the command was successfully sent
2998 main.FALSE if the cli responded with an error or given
2999 incorrect input
3000 """
3001 try:
3002 if not isinstance( appName, types.StringType ):
3003 main.log.error( self.name + ".activateApp(): appName must be" +
3004 " a string" )
3005 return main.FALSE
3006 status = self.appStatus( appName )
3007 if status == "INSTALLED":
3008 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003009 if check and response == main.TRUE:
3010 for i in range(10): # try 10 times then give up
3011 # TODO: Check with Thomas about this delay
3012 status = self.appStatus( appName )
3013 if status == "ACTIVE":
3014 return main.TRUE
3015 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003016 main.log.debug( "The state of application " +
3017 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003018 time.sleep( 1 )
3019 return main.FALSE
3020 else: # not 'check' or command didn't succeed
3021 return response
Jon Hall146f1522015-03-24 15:33:24 -07003022 elif status == "ACTIVE":
3023 return main.TRUE
3024 elif status == "UNINSTALLED":
3025 main.log.error( self.name + ": Tried to activate the " +
3026 "application '" + appName + "' which is not " +
3027 "installed." )
3028 else:
3029 main.log.error( "Unexpected return value from appStatus: " +
3030 str( status ) )
3031 return main.ERROR
3032 except TypeError:
3033 main.log.exception( self.name + ": Object not as expected" )
3034 return main.ERROR
3035 except pexpect.EOF:
3036 main.log.error( self.name + ": EOF exception found" )
3037 main.log.error( self.name + ": " + self.handle.before )
3038 main.cleanup()
3039 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003040 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003041 main.log.exception( self.name + ": Uncaught exception!" )
3042 main.cleanup()
3043 main.exit()
3044
Jon Hallbd16b922015-03-26 17:53:15 -07003045 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003046 """
3047 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003048 appName is the hierarchical app name, not the feature name
3049 If check is True, method will check the status of the app after the
3050 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003051 Returns main.TRUE if the command was successfully sent
3052 main.FALSE if the cli responded with an error or given
3053 incorrect input
3054 """
3055 try:
3056 if not isinstance( appName, types.StringType ):
3057 main.log.error( self.name + ".deactivateApp(): appName must " +
3058 "be a string" )
3059 return main.FALSE
3060 status = self.appStatus( appName )
3061 if status == "INSTALLED":
3062 return main.TRUE
3063 elif status == "ACTIVE":
3064 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003065 if check and response == main.TRUE:
3066 for i in range(10): # try 10 times then give up
3067 status = self.appStatus( appName )
3068 if status == "INSTALLED":
3069 return main.TRUE
3070 else:
3071 time.sleep( 1 )
3072 return main.FALSE
3073 else: # not check or command didn't succeed
3074 return response
Jon Hall146f1522015-03-24 15:33:24 -07003075 elif status == "UNINSTALLED":
3076 main.log.warn( self.name + ": Tried to deactivate the " +
3077 "application '" + appName + "' which is not " +
3078 "installed." )
3079 return main.TRUE
3080 else:
3081 main.log.error( "Unexpected return value from appStatus: " +
3082 str( status ) )
3083 return main.ERROR
3084 except TypeError:
3085 main.log.exception( self.name + ": Object not as expected" )
3086 return main.ERROR
3087 except pexpect.EOF:
3088 main.log.error( self.name + ": EOF exception found" )
3089 main.log.error( self.name + ": " + self.handle.before )
3090 main.cleanup()
3091 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003092 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003093 main.log.exception( self.name + ": Uncaught exception!" )
3094 main.cleanup()
3095 main.exit()
3096
Jon Hallbd16b922015-03-26 17:53:15 -07003097 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003098 """
3099 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003100 appName is the hierarchical app name, not the feature name
3101 If check is True, method will check the status of the app after the
3102 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003103 Returns main.TRUE if the command was successfully sent
3104 main.FALSE if the cli responded with an error or given
3105 incorrect input
3106 """
3107 # TODO: check with Thomas about the state machine for apps
3108 try:
3109 if not isinstance( appName, types.StringType ):
3110 main.log.error( self.name + ".uninstallApp(): appName must " +
3111 "be a string" )
3112 return main.FALSE
3113 status = self.appStatus( appName )
3114 if status == "INSTALLED":
3115 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003116 if check and response == main.TRUE:
3117 for i in range(10): # try 10 times then give up
3118 status = self.appStatus( appName )
3119 if status == "UNINSTALLED":
3120 return main.TRUE
3121 else:
3122 time.sleep( 1 )
3123 return main.FALSE
3124 else: # not check or command didn't succeed
3125 return response
Jon Hall146f1522015-03-24 15:33:24 -07003126 elif status == "ACTIVE":
3127 main.log.warn( self.name + ": Tried to uninstall the " +
3128 "application '" + appName + "' which is " +
3129 "currently active." )
3130 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003131 if check and response == main.TRUE:
3132 for i in range(10): # try 10 times then give up
3133 status = self.appStatus( appName )
3134 if status == "UNINSTALLED":
3135 return main.TRUE
3136 else:
3137 time.sleep( 1 )
3138 return main.FALSE
3139 else: # not check or command didn't succeed
3140 return response
Jon Hall146f1522015-03-24 15:33:24 -07003141 elif status == "UNINSTALLED":
3142 return main.TRUE
3143 else:
3144 main.log.error( "Unexpected return value from appStatus: " +
3145 str( status ) )
3146 return main.ERROR
3147 except TypeError:
3148 main.log.exception( self.name + ": Object not as expected" )
3149 return main.ERROR
3150 except pexpect.EOF:
3151 main.log.error( self.name + ": EOF exception found" )
3152 main.log.error( self.name + ": " + self.handle.before )
3153 main.cleanup()
3154 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003155 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003156 main.log.exception( self.name + ": Uncaught exception!" )
3157 main.cleanup()
3158 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003159
3160 def appIDs( self, jsonFormat=True ):
3161 """
3162 Show the mappings between app id and app names given by the 'app-ids'
3163 cli command
3164 """
3165 try:
3166 cmdStr = "app-ids"
3167 if jsonFormat:
3168 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003169 output = self.sendline( cmdStr )
3170 assert "Error executing command" not in output
3171 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003172 except AssertionError:
3173 main.log.error( "Error in processing onos:app-ids command: " +
3174 str( output ) )
3175 return None
3176 except TypeError:
3177 main.log.exception( self.name + ": Object not as expected" )
3178 return None
3179 except pexpect.EOF:
3180 main.log.error( self.name + ": EOF exception found" )
3181 main.log.error( self.name + ": " + self.handle.before )
3182 main.cleanup()
3183 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003184 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003185 main.log.exception( self.name + ": Uncaught exception!" )
3186 main.cleanup()
3187 main.exit()
3188
3189 def appToIDCheck( self ):
3190 """
3191 This method will check that each application's ID listed in 'apps' is
3192 the same as the ID listed in 'app-ids'. The check will also check that
3193 there are no duplicate IDs issued. Note that an app ID should be
3194 a globaly unique numerical identifier for app/app-like features. Once
3195 an ID is registered, the ID is never freed up so that if an app is
3196 reinstalled it will have the same ID.
3197
3198 Returns: main.TRUE if the check passes and
3199 main.FALSE if the check fails or
3200 main.ERROR if there is some error in processing the test
3201 """
3202 try:
Jon Hall390696c2015-05-05 17:13:41 -07003203 bail = False
3204 ids = self.appIDs( jsonFormat=True )
3205 if ids:
3206 ids = json.loads( ids )
3207 else:
3208 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3209 bail = True
3210 apps = self.apps( jsonFormat=True )
3211 if apps:
3212 apps = json.loads( apps )
3213 else:
3214 main.log.error( "apps returned nothing:" + repr( apps ) )
3215 bail = True
3216 if bail:
3217 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003218 result = main.TRUE
3219 for app in apps:
3220 appID = app.get( 'id' )
3221 if appID is None:
3222 main.log.error( "Error parsing app: " + str( app ) )
3223 result = main.FALSE
3224 appName = app.get( 'name' )
3225 if appName is None:
3226 main.log.error( "Error parsing app: " + str( app ) )
3227 result = main.FALSE
3228 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003229 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003230 # main.log.debug( "Comparing " + str( app ) + " to " +
3231 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003232 if not current: # if ids doesn't have this id
3233 result = main.FALSE
3234 main.log.error( "'app-ids' does not have the ID for " +
3235 str( appName ) + " that apps does." )
3236 elif len( current ) > 1:
3237 # there is more than one app with this ID
3238 result = main.FALSE
3239 # We will log this later in the method
3240 elif not current[0][ 'name' ] == appName:
3241 currentName = current[0][ 'name' ]
3242 result = main.FALSE
3243 main.log.error( "'app-ids' has " + str( currentName ) +
3244 " registered under id:" + str( appID ) +
3245 " but 'apps' has " + str( appName ) )
3246 else:
3247 pass # id and name match!
3248 # now make sure that app-ids has no duplicates
3249 idsList = []
3250 namesList = []
3251 for item in ids:
3252 idsList.append( item[ 'id' ] )
3253 namesList.append( item[ 'name' ] )
3254 if len( idsList ) != len( set( idsList ) ) or\
3255 len( namesList ) != len( set( namesList ) ):
3256 main.log.error( "'app-ids' has some duplicate entries: \n"
3257 + json.dumps( ids,
3258 sort_keys=True,
3259 indent=4,
3260 separators=( ',', ': ' ) ) )
3261 result = main.FALSE
3262 return result
3263 except ( ValueError, TypeError ):
3264 main.log.exception( self.name + ": Object not as expected" )
3265 return main.ERROR
3266 except pexpect.EOF:
3267 main.log.error( self.name + ": EOF exception found" )
3268 main.log.error( self.name + ": " + self.handle.before )
3269 main.cleanup()
3270 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003271 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003272 main.log.exception( self.name + ": Uncaught exception!" )
3273 main.cleanup()
3274 main.exit()
3275
Jon Hallfb760a02015-04-13 15:35:03 -07003276 def getCfg( self, component=None, propName=None, short=False,
3277 jsonFormat=True ):
3278 """
3279 Get configuration settings from onos cli
3280 Optional arguments:
3281 component - Optionally only list configurations for a specific
3282 component. If None, all components with configurations
3283 are displayed. Case Sensitive string.
3284 propName - If component is specified, propName option will show
3285 only this specific configuration from that component.
3286 Case Sensitive string.
3287 jsonFormat - Returns output as json. Note that this will override
3288 the short option
3289 short - Short, less verbose, version of configurations.
3290 This is overridden by the json option
3291 returns:
3292 Output from cli as a string or None on error
3293 """
3294 try:
3295 baseStr = "cfg"
3296 cmdStr = " get"
3297 componentStr = ""
3298 if component:
3299 componentStr += " " + component
3300 if propName:
3301 componentStr += " " + propName
3302 if jsonFormat:
3303 baseStr += " -j"
3304 elif short:
3305 baseStr += " -s"
3306 output = self.sendline( baseStr + cmdStr + componentStr )
3307 assert "Error executing command" not in output
3308 return output
3309 except AssertionError:
3310 main.log.error( "Error in processing 'cfg get' command: " +
3311 str( output ) )
3312 return None
3313 except TypeError:
3314 main.log.exception( self.name + ": Object not as expected" )
3315 return None
3316 except pexpect.EOF:
3317 main.log.error( self.name + ": EOF exception found" )
3318 main.log.error( self.name + ": " + self.handle.before )
3319 main.cleanup()
3320 main.exit()
3321 except Exception:
3322 main.log.exception( self.name + ": Uncaught exception!" )
3323 main.cleanup()
3324 main.exit()
3325
3326 def setCfg( self, component, propName, value=None, check=True ):
3327 """
3328 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003329 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003330 component - The case sensitive name of the component whose
3331 property is to be set
3332 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003333 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003334 value - The value to set the property to. If None, will unset the
3335 property and revert it to it's default value(if applicable)
3336 check - Boolean, Check whether the option was successfully set this
3337 only applies when a value is given.
3338 returns:
3339 main.TRUE on success or main.FALSE on failure. If check is False,
3340 will return main.TRUE unless there is an error
3341 """
3342 try:
3343 baseStr = "cfg"
3344 cmdStr = " set " + str( component ) + " " + str( propName )
3345 if value is not None:
3346 cmdStr += " " + str( value )
3347 output = self.sendline( baseStr + cmdStr )
3348 assert "Error executing command" not in output
3349 if value and check:
3350 results = self.getCfg( component=str( component ),
3351 propName=str( propName ),
3352 jsonFormat=True )
3353 # Check if current value is what we just set
3354 try:
3355 jsonOutput = json.loads( results )
3356 current = jsonOutput[ 'value' ]
3357 except ( ValueError, TypeError ):
3358 main.log.exception( "Error parsing cfg output" )
3359 main.log.error( "output:" + repr( results ) )
3360 return main.FALSE
3361 if current == str( value ):
3362 return main.TRUE
3363 return main.FALSE
3364 return main.TRUE
3365 except AssertionError:
3366 main.log.error( "Error in processing 'cfg set' command: " +
3367 str( output ) )
3368 return main.FALSE
3369 except TypeError:
3370 main.log.exception( self.name + ": Object not as expected" )
3371 return main.FALSE
3372 except pexpect.EOF:
3373 main.log.error( self.name + ": EOF exception found" )
3374 main.log.error( self.name + ": " + self.handle.before )
3375 main.cleanup()
3376 main.exit()
3377 except Exception:
3378 main.log.exception( self.name + ": Uncaught exception!" )
3379 main.cleanup()
3380 main.exit()
3381
Jon Hall390696c2015-05-05 17:13:41 -07003382 def setTestAdd( self, setName, values ):
3383 """
3384 CLI command to add elements to a distributed set.
3385 Arguments:
3386 setName - The name of the set to add to.
3387 values - The value(s) to add to the set, space seperated.
3388 Example usages:
3389 setTestAdd( "set1", "a b c" )
3390 setTestAdd( "set2", "1" )
3391 returns:
3392 main.TRUE on success OR
3393 main.FALSE if elements were already in the set OR
3394 main.ERROR on error
3395 """
3396 try:
3397 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3398 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003399 try:
3400 # TODO: Maybe make this less hardcoded
3401 # ConsistentMap Exceptions
3402 assert "org.onosproject.store.service" not in output
3403 # Node not leader
3404 assert "java.lang.IllegalStateException" not in output
3405 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003406 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003407 "command: " + str( output ) )
3408 retryTime = 30 # Conservative time, given by Madan
3409 main.log.info( "Waiting " + str( retryTime ) +
3410 "seconds before retrying." )
3411 time.sleep( retryTime ) # Due to change in mastership
3412 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003413 assert "Error executing command" not in output
3414 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3415 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3416 main.log.info( self.name + ": " + output )
3417 if re.search( positiveMatch, output):
3418 return main.TRUE
3419 elif re.search( negativeMatch, output):
3420 return main.FALSE
3421 else:
3422 main.log.error( self.name + ": setTestAdd did not" +
3423 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003424 main.log.debug( self.name + " actual: " + repr( output ) )
3425 return main.ERROR
3426 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003427 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003428 str( output ) )
3429 return main.ERROR
3430 except TypeError:
3431 main.log.exception( self.name + ": Object not as expected" )
3432 return main.ERROR
3433 except pexpect.EOF:
3434 main.log.error( self.name + ": EOF exception found" )
3435 main.log.error( self.name + ": " + self.handle.before )
3436 main.cleanup()
3437 main.exit()
3438 except Exception:
3439 main.log.exception( self.name + ": Uncaught exception!" )
3440 main.cleanup()
3441 main.exit()
3442
3443 def setTestRemove( self, setName, values, clear=False, retain=False ):
3444 """
3445 CLI command to remove elements from a distributed set.
3446 Required arguments:
3447 setName - The name of the set to remove from.
3448 values - The value(s) to remove from the set, space seperated.
3449 Optional arguments:
3450 clear - Clear all elements from the set
3451 retain - Retain only the given values. (intersection of the
3452 original set and the given set)
3453 returns:
3454 main.TRUE on success OR
3455 main.FALSE if the set was not changed OR
3456 main.ERROR on error
3457 """
3458 try:
3459 cmdStr = "set-test-remove "
3460 if clear:
3461 cmdStr += "-c " + str( setName )
3462 elif retain:
3463 cmdStr += "-r " + str( setName ) + " " + str( values )
3464 else:
3465 cmdStr += str( setName ) + " " + str( values )
3466 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003467 try:
3468 # TODO: Maybe make this less hardcoded
3469 # ConsistentMap Exceptions
3470 assert "org.onosproject.store.service" not in output
3471 # Node not leader
3472 assert "java.lang.IllegalStateException" not in output
3473 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003474 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003475 "command: " + str( output ) )
3476 retryTime = 30 # Conservative time, given by Madan
3477 main.log.info( "Waiting " + str( retryTime ) +
3478 "seconds before retrying." )
3479 time.sleep( retryTime ) # Due to change in mastership
3480 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003481 assert "Error executing command" not in output
3482 main.log.info( self.name + ": " + output )
3483 if clear:
3484 pattern = "Set " + str( setName ) + " cleared"
3485 if re.search( pattern, output ):
3486 return main.TRUE
3487 elif retain:
3488 positivePattern = str( setName ) + " was pruned to contain " +\
3489 "only elements of set \[(.*)\]"
3490 negativePattern = str( setName ) + " was not changed by " +\
3491 "retaining only elements of the set " +\
3492 "\[(.*)\]"
3493 if re.search( positivePattern, output ):
3494 return main.TRUE
3495 elif re.search( negativePattern, output ):
3496 return main.FALSE
3497 else:
3498 positivePattern = "\[(.*)\] was removed from the set " +\
3499 str( setName )
3500 if ( len( values.split() ) == 1 ):
3501 negativePattern = "\[(.*)\] was not in set " +\
3502 str( setName )
3503 else:
3504 negativePattern = "No element of \[(.*)\] was in set " +\
3505 str( setName )
3506 if re.search( positivePattern, output ):
3507 return main.TRUE
3508 elif re.search( negativePattern, output ):
3509 return main.FALSE
3510 main.log.error( self.name + ": setTestRemove did not" +
3511 " match expected output" )
3512 main.log.debug( self.name + " expected: " + pattern )
3513 main.log.debug( self.name + " actual: " + repr( output ) )
3514 return main.ERROR
3515 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003516 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003517 str( output ) )
3518 return main.ERROR
3519 except TypeError:
3520 main.log.exception( self.name + ": Object not as expected" )
3521 return main.ERROR
3522 except pexpect.EOF:
3523 main.log.error( self.name + ": EOF exception found" )
3524 main.log.error( self.name + ": " + self.handle.before )
3525 main.cleanup()
3526 main.exit()
3527 except Exception:
3528 main.log.exception( self.name + ": Uncaught exception!" )
3529 main.cleanup()
3530 main.exit()
3531
3532 def setTestGet( self, setName, values="" ):
3533 """
3534 CLI command to get the elements in a distributed set.
3535 Required arguments:
3536 setName - The name of the set to remove from.
3537 Optional arguments:
3538 values - The value(s) to check if in the set, space seperated.
3539 returns:
3540 main.ERROR on error OR
3541 A list of elements in the set if no optional arguments are
3542 supplied OR
3543 A tuple containing the list then:
3544 main.FALSE if the given values are not in the set OR
3545 main.TRUE if the given values are in the set OR
3546 """
3547 try:
3548 values = str( values ).strip()
3549 setName = str( setName ).strip()
3550 length = len( values.split() )
3551 containsCheck = None
3552 # Patterns to match
3553 setPattern = "\[(.*)\]"
3554 pattern = "Items in set " + setName + ":\n" + setPattern
3555 containsTrue = "Set " + setName + " contains the value " + values
3556 containsFalse = "Set " + setName + " did not contain the value " +\
3557 values
3558 containsAllTrue = "Set " + setName + " contains the the subset " +\
3559 setPattern
3560 containsAllFalse = "Set " + setName + " did not contain the the" +\
3561 " subset " + setPattern
3562
3563 cmdStr = "set-test-get "
3564 cmdStr += setName + " " + values
3565 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003566 try:
3567 # TODO: Maybe make this less hardcoded
3568 # ConsistentMap Exceptions
3569 assert "org.onosproject.store.service" not in output
3570 # Node not leader
3571 assert "java.lang.IllegalStateException" not in output
3572 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003573 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003574 "command: " + str( output ) )
3575 retryTime = 30 # Conservative time, given by Madan
3576 main.log.info( "Waiting " + str( retryTime ) +
3577 "seconds before retrying." )
3578 time.sleep( retryTime ) # Due to change in mastership
3579 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003580 assert "Error executing command" not in output
3581 main.log.info( self.name + ": " + output )
3582
3583 if length == 0:
3584 match = re.search( pattern, output )
3585 else: # if given values
3586 if length == 1: # Contains output
3587 patternTrue = pattern + "\n" + containsTrue
3588 patternFalse = pattern + "\n" + containsFalse
3589 else: # ContainsAll output
3590 patternTrue = pattern + "\n" + containsAllTrue
3591 patternFalse = pattern + "\n" + containsAllFalse
3592 matchTrue = re.search( patternTrue, output )
3593 matchFalse = re.search( patternFalse, output )
3594 if matchTrue:
3595 containsCheck = main.TRUE
3596 match = matchTrue
3597 elif matchFalse:
3598 containsCheck = main.FALSE
3599 match = matchFalse
3600 else:
3601 main.log.error( self.name + " setTestGet did not match " +\
3602 "expected output" )
3603 main.log.debug( self.name + " expected: " + pattern )
3604 main.log.debug( self.name + " actual: " + repr( output ) )
3605 match = None
3606 if match:
3607 setMatch = match.group( 1 )
3608 if setMatch == '':
3609 setList = []
3610 else:
3611 setList = setMatch.split( ", " )
3612 if length > 0:
3613 return ( setList, containsCheck )
3614 else:
3615 return setList
3616 else: # no match
3617 main.log.error( self.name + ": setTestGet did not" +
3618 " match expected output" )
3619 main.log.debug( self.name + " expected: " + pattern )
3620 main.log.debug( self.name + " actual: " + repr( output ) )
3621 return main.ERROR
3622 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003623 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003624 str( output ) )
3625 return main.ERROR
3626 except TypeError:
3627 main.log.exception( self.name + ": Object not as expected" )
3628 return main.ERROR
3629 except pexpect.EOF:
3630 main.log.error( self.name + ": EOF exception found" )
3631 main.log.error( self.name + ": " + self.handle.before )
3632 main.cleanup()
3633 main.exit()
3634 except Exception:
3635 main.log.exception( self.name + ": Uncaught exception!" )
3636 main.cleanup()
3637 main.exit()
3638
3639 def setTestSize( self, setName ):
3640 """
3641 CLI command to get the elements in a distributed set.
3642 Required arguments:
3643 setName - The name of the set to remove from.
3644 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003645 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003646 None on error
3647 """
3648 try:
3649 # TODO: Should this check against the number of elements returned
3650 # and then return true/false based on that?
3651 setName = str( setName ).strip()
3652 # Patterns to match
3653 setPattern = "\[(.*)\]"
3654 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3655 setPattern
3656 cmdStr = "set-test-get -s "
3657 cmdStr += setName
3658 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003659 try:
3660 # TODO: Maybe make this less hardcoded
3661 # ConsistentMap Exceptions
3662 assert "org.onosproject.store.service" not in output
3663 # Node not leader
3664 assert "java.lang.IllegalStateException" not in output
3665 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003666 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003667 "command: " + str( output ) )
3668 retryTime = 30 # Conservative time, given by Madan
3669 main.log.info( "Waiting " + str( retryTime ) +
3670 "seconds before retrying." )
3671 time.sleep( retryTime ) # Due to change in mastership
3672 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003673 assert "Error executing command" not in output
3674 main.log.info( self.name + ": " + output )
3675 match = re.search( pattern, output )
3676 if match:
3677 setSize = int( match.group( 1 ) )
3678 setMatch = match.group( 2 )
3679 if len( setMatch.split() ) == setSize:
3680 main.log.info( "The size returned by " + self.name +
3681 " matches the number of elements in " +
3682 "the returned set" )
3683 else:
3684 main.log.error( "The size returned by " + self.name +
3685 " does not match the number of " +
3686 "elements in the returned set." )
3687 return setSize
3688 else: # no match
3689 main.log.error( self.name + ": setTestGet did not" +
3690 " match expected output" )
3691 main.log.debug( self.name + " expected: " + pattern )
3692 main.log.debug( self.name + " actual: " + repr( output ) )
3693 return None
3694 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003695 main.log.error( "Error in processing '" + cmdStr + "' command: " +
Jon Hall390696c2015-05-05 17:13:41 -07003696 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003697 return None
Jon Hall390696c2015-05-05 17:13:41 -07003698 except TypeError:
3699 main.log.exception( self.name + ": Object not as expected" )
3700 return None
3701 except pexpect.EOF:
3702 main.log.error( self.name + ": EOF exception found" )
3703 main.log.error( self.name + ": " + self.handle.before )
3704 main.cleanup()
3705 main.exit()
3706 except Exception:
3707 main.log.exception( self.name + ": Uncaught exception!" )
3708 main.cleanup()
3709 main.exit()
3710
Jon Hall80daded2015-05-27 16:07:00 -07003711 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003712 """
3713 Command to list the various counters in the system.
3714 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003715 if jsonFormat, a string of the json object returned by the cli
3716 command
3717 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003718 None on error
3719 """
Jon Hall390696c2015-05-05 17:13:41 -07003720 try:
3721 counters = {}
3722 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003723 if jsonFormat:
3724 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003725 output = self.sendline( cmdStr )
3726 assert "Error executing command" not in output
3727 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003728 return output
Jon Hall390696c2015-05-05 17:13:41 -07003729 except AssertionError:
3730 main.log.error( "Error in processing 'counters' command: " +
3731 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003732 return None
Jon Hall390696c2015-05-05 17:13:41 -07003733 except TypeError:
3734 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003735 return None
Jon Hall390696c2015-05-05 17:13:41 -07003736 except pexpect.EOF:
3737 main.log.error( self.name + ": EOF exception found" )
3738 main.log.error( self.name + ": " + self.handle.before )
3739 main.cleanup()
3740 main.exit()
3741 except Exception:
3742 main.log.exception( self.name + ": Uncaught exception!" )
3743 main.cleanup()
3744 main.exit()
3745
Jon Halle1a3b752015-07-22 13:02:46 -07003746 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003747 """
Jon Halle1a3b752015-07-22 13:02:46 -07003748 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003749 Required arguments:
3750 counter - The name of the counter to increment.
3751 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003752 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003753 inMemory - use in memory map for the counter
3754 returns:
3755 integer value of the counter or
3756 None on Error
3757 """
3758 try:
3759 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003760 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003761 cmdStr = "counter-test-increment "
3762 if inMemory:
3763 cmdStr += "-i "
3764 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003765 if delta != 1:
3766 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003767 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003768 try:
3769 # TODO: Maybe make this less hardcoded
3770 # ConsistentMap Exceptions
3771 assert "org.onosproject.store.service" not in output
3772 # Node not leader
3773 assert "java.lang.IllegalStateException" not in output
3774 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003775 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003776 "command: " + str( output ) )
3777 retryTime = 30 # Conservative time, given by Madan
3778 main.log.info( "Waiting " + str( retryTime ) +
3779 "seconds before retrying." )
3780 time.sleep( retryTime ) # Due to change in mastership
3781 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003782 assert "Error executing command" not in output
3783 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003784 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003785 match = re.search( pattern, output )
3786 if match:
3787 return int( match.group( 1 ) )
3788 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003789 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003790 " match expected output." )
3791 main.log.debug( self.name + " expected: " + pattern )
3792 main.log.debug( self.name + " actual: " + repr( output ) )
3793 return None
3794 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003795 main.log.error( "Error in processing '" + cmdStr + "'" +
Jon Hall390696c2015-05-05 17:13:41 -07003796 " command: " + str( output ) )
3797 return None
3798 except TypeError:
3799 main.log.exception( self.name + ": Object not as expected" )
3800 return None
3801 except pexpect.EOF:
3802 main.log.error( self.name + ": EOF exception found" )
3803 main.log.error( self.name + ": " + self.handle.before )
3804 main.cleanup()
3805 main.exit()
3806 except Exception:
3807 main.log.exception( self.name + ": Uncaught exception!" )
3808 main.cleanup()
3809 main.exit()
3810
Jon Halle1a3b752015-07-22 13:02:46 -07003811 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
3812 """
3813 CLI command to get a distributed counter then add a delta to it.
3814 Required arguments:
3815 counter - The name of the counter to increment.
3816 Optional arguments:
3817 delta - The long to add to the counter
3818 inMemory - use in memory map for the counter
3819 returns:
3820 integer value of the counter or
3821 None on Error
3822 """
3823 try:
3824 counter = str( counter )
3825 delta = int( delta )
3826 cmdStr = "counter-test-increment -g "
3827 if inMemory:
3828 cmdStr += "-i "
3829 cmdStr += counter
3830 if delta != 1:
3831 cmdStr += " " + str( delta )
3832 output = self.sendline( cmdStr )
3833 try:
3834 # TODO: Maybe make this less hardcoded
3835 # ConsistentMap Exceptions
3836 assert "org.onosproject.store.service" not in output
3837 # Node not leader
3838 assert "java.lang.IllegalStateException" not in output
3839 except AssertionError:
3840 main.log.error( "Error in processing '" + cmdStr + "' " +
3841 "command: " + str( output ) )
3842 retryTime = 30 # Conservative time, given by Madan
3843 main.log.info( "Waiting " + str( retryTime ) +
3844 "seconds before retrying." )
3845 time.sleep( retryTime ) # Due to change in mastership
3846 output = self.sendline( cmdStr )
3847 assert "Error executing command" not in output
3848 main.log.info( self.name + ": " + output )
3849 pattern = counter + " was updated to (-?\d+)"
3850 match = re.search( pattern, output )
3851 if match:
3852 return int( match.group( 1 ) )
3853 else:
3854 main.log.error( self.name + ": counterTestGetAndAdd did not" +
3855 " match expected output." )
3856 main.log.debug( self.name + " expected: " + pattern )
3857 main.log.debug( self.name + " actual: " + repr( output ) )
3858 return None
3859 except AssertionError:
3860 main.log.error( "Error in processing '" + cmdStr + "'" +
3861 " command: " + str( output ) )
3862 return None
3863 except TypeError:
3864 main.log.exception( self.name + ": Object not as expected" )
3865 return None
3866 except pexpect.EOF:
3867 main.log.error( self.name + ": EOF exception found" )
3868 main.log.error( self.name + ": " + self.handle.before )
3869 main.cleanup()
3870 main.exit()
3871 except Exception:
3872 main.log.exception( self.name + ": Uncaught exception!" )
3873 main.cleanup()
3874 main.exit()
3875
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003876 def summary( self, jsonFormat=True ):
3877 """
3878 Description: Execute summary command in onos
3879 Returns: json object ( summary -j ), returns main.FALSE if there is
3880 no output
3881
3882 """
3883 try:
3884 cmdStr = "summary"
3885 if jsonFormat:
3886 cmdStr += " -j"
3887 handle = self.sendline( cmdStr )
3888
3889 if re.search( "Error:", handle ):
3890 main.log.error( self.name + ": summary() response: " +
3891 str( handle ) )
3892 if not handle:
3893 main.log.error( self.name + ": There is no output in " +
3894 "summary command" )
3895 return main.FALSE
3896 return handle
3897 except TypeError:
3898 main.log.exception( self.name + ": Object not as expected" )
3899 return None
3900 except pexpect.EOF:
3901 main.log.error( self.name + ": EOF exception found" )
3902 main.log.error( self.name + ": " + self.handle.before )
3903 main.cleanup()
3904 main.exit()
3905 except Exception:
3906 main.log.exception( self.name + ": Uncaught exception!" )
3907 main.cleanup()
3908 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07003909
3910 def transactionalMapGet( self, keyName, inMemory=False ):
3911 """
3912 CLI command to get the value of a key in a consistent map using
3913 transactions. This a test function and can only get keys from the
3914 test map hard coded into the cli command
3915 Required arguments:
3916 keyName - The name of the key to get
3917 Optional arguments:
3918 inMemory - use in memory map for the counter
3919 returns:
3920 The string value of the key or
3921 None on Error
3922 """
3923 try:
3924 keyName = str( keyName )
3925 cmdStr = "transactional-map-test-get "
3926 if inMemory:
3927 cmdStr += "-i "
3928 cmdStr += keyName
3929 output = self.sendline( cmdStr )
3930 try:
3931 # TODO: Maybe make this less hardcoded
3932 # ConsistentMap Exceptions
3933 assert "org.onosproject.store.service" not in output
3934 # Node not leader
3935 assert "java.lang.IllegalStateException" not in output
3936 except AssertionError:
3937 main.log.error( "Error in processing '" + cmdStr + "' " +
3938 "command: " + str( output ) )
3939 return None
3940 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
3941 if "Key " + keyName + " not found." in output:
3942 return None
3943 else:
3944 match = re.search( pattern, output )
3945 if match:
3946 return match.groupdict()[ 'value' ]
3947 else:
3948 main.log.error( self.name + ": transactionlMapGet did not" +
3949 " match expected output." )
3950 main.log.debug( self.name + " expected: " + pattern )
3951 main.log.debug( self.name + " actual: " + repr( output ) )
3952 return None
3953 except TypeError:
3954 main.log.exception( self.name + ": Object not as expected" )
3955 return None
3956 except pexpect.EOF:
3957 main.log.error( self.name + ": EOF exception found" )
3958 main.log.error( self.name + ": " + self.handle.before )
3959 main.cleanup()
3960 main.exit()
3961 except Exception:
3962 main.log.exception( self.name + ": Uncaught exception!" )
3963 main.cleanup()
3964 main.exit()
3965
3966 def transactionalMapPut( self, numKeys, value, inMemory=False ):
3967 """
3968 CLI command to put a value into 'numKeys' number of keys in a
3969 consistent map using transactions. This a test function and can only
3970 put into keys named 'Key#' of the test map hard coded into the cli command
3971 Required arguments:
3972 numKeys - Number of keys to add the value to
3973 value - The string value to put into the keys
3974 Optional arguments:
3975 inMemory - use in memory map for the counter
3976 returns:
3977 A dictionary whose keys are the name of the keys put into the map
3978 and the values of the keys are dictionaries whose key-values are
3979 'value': value put into map and optionaly
3980 'oldValue': Previous value in the key or
3981 None on Error
3982
3983 Example output
3984 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
3985 'Key2': {'value': 'Testing'} }
3986 """
3987 try:
3988 numKeys = str( numKeys )
3989 value = str( value )
3990 cmdStr = "transactional-map-test-put "
3991 if inMemory:
3992 cmdStr += "-i "
3993 cmdStr += numKeys + " " + value
3994 output = self.sendline( cmdStr )
3995 try:
3996 # TODO: Maybe make this less hardcoded
3997 # ConsistentMap Exceptions
3998 assert "org.onosproject.store.service" not in output
3999 # Node not leader
4000 assert "java.lang.IllegalStateException" not in output
4001 except AssertionError:
4002 main.log.error( "Error in processing '" + cmdStr + "' " +
4003 "command: " + str( output ) )
4004 return None
4005 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4006 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4007 results = {}
4008 for line in output.splitlines():
4009 new = re.search( newPattern, line )
4010 updated = re.search( updatedPattern, line )
4011 if new:
4012 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4013 elif updated:
4014 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
4015 'oldValue': updated.groupdict()[ 'oldValue' ] }
4016 else:
4017 main.log.error( self.name + ": transactionlMapGet did not" +
4018 " match expected output." )
4019 main.log.debug( self.name + " expected: " + pattern )
4020 main.log.debug( self.name + " actual: " + repr( output ) )
4021 return results
4022 except TypeError:
4023 main.log.exception( self.name + ": Object not as expected" )
4024 return None
4025 except pexpect.EOF:
4026 main.log.error( self.name + ": EOF exception found" )
4027 main.log.error( self.name + ": " + self.handle.before )
4028 main.cleanup()
4029 main.exit()
4030 except Exception:
4031 main.log.exception( self.name + ": Uncaught exception!" )
4032 main.cleanup()
4033 main.exit()
acsmarsdaea66c2015-09-03 11:44:06 -07004034 def maps( self, jsonFormat=True ):
4035 """
4036 Description: Returns result of onos:maps
4037 Optional:
4038 * jsonFormat: enable json formatting of output
4039 """
4040 try:
4041 cmdStr = "maps"
4042 if jsonFormat:
4043 cmdStr += " -j"
4044 handle = self.sendline( cmdStr )
4045 return handle
4046 except TypeError:
4047 main.log.exception( self.name + ": Object not as expected" )
4048 return None
4049 except pexpect.EOF:
4050 main.log.error( self.name + ": EOF exception found" )
4051 main.log.error( self.name + ": " + self.handle.before )
4052 main.cleanup()
4053 main.exit()
4054 except Exception:
4055 main.log.exception( self.name + ": Uncaught exception!" )
4056 main.cleanup()
4057 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004058
4059 def getSwController( self, uri, jsonFormat=True ):
4060 """
4061 Descrition: Gets the controller information from the device
4062 """
4063 try:
4064 cmd = "device-controllers "
4065 if jsonFormat:
4066 cmd += "-j "
4067 response = self.sendline( cmd + uri )
4068 return response
4069 except TypeError:
4070 main.log.exception( self.name + ": Object not as expected" )
4071 return None
4072 except pexpect.EOF:
4073 main.log.error( self.name + ": EOF exception found" )
4074 main.log.error( self.name + ": " + self.handle.before )
4075 main.cleanup()
4076 main.exit()
4077 except Exception:
4078 main.log.exception( self.name + ": Uncaught exception!" )
4079 main.cleanup()
4080 main.exit()
4081
4082 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4083 """
4084 Descrition: sets the controller(s) for the specified device
4085
4086 Parameters:
4087 Required: uri - String: The uri of the device(switch).
4088 ip - String or List: The ip address of the controller.
4089 This parameter can be formed in a couple of different ways.
4090 VALID:
4091 10.0.0.1 - just the ip address
4092 tcp:10.0.0.1 - the protocol and the ip address
4093 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4094 so that you can add controllers with different
4095 protocols and ports
4096 INVALID:
4097 10.0.0.1:6653 - this is not supported by ONOS
4098
4099 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4100 port - The port number.
4101 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4102
4103 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4104 """
4105 try:
4106 cmd = "device-setcontrollers"
4107
4108 if jsonFormat:
4109 cmd += " -j"
4110 cmd += " " + uri
4111 if isinstance( ip, str ):
4112 ip = [ip]
4113 for item in ip:
4114 if ":" in item:
4115 sitem = item.split( ":" )
4116 if len(sitem) == 3:
4117 cmd += " " + item
4118 elif "." in sitem[1]:
4119 cmd += " {}:{}".format(item, port)
4120 else:
4121 main.log.error( "Malformed entry: " + item )
4122 raise TypeError
4123 else:
4124 cmd += " {}:{}:{}".format( proto, item, port )
4125
4126 response = self.sendline( cmd )
4127
4128 if "Error" in response:
4129 main.log.error( response )
4130 return main.FALSE
4131
GlennRC050596c2015-11-18 17:06:41 -08004132 return main.TRUE
4133
4134 except TypeError:
4135 main.log.exception( self.name + ": Object not as expected" )
4136 return main.FALSE
4137 except pexpect.EOF:
4138 main.log.error( self.name + ": EOF exception found" )
4139 main.log.error( self.name + ": " + self.handle.before )
4140 main.cleanup()
4141 main.exit()
4142 except Exception:
4143 main.log.exception( self.name + ": Uncaught exception!" )
4144 main.cleanup()
4145 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004146
4147 def removeDevice( self, device ):
4148 '''
4149 Description:
4150 Remove a device from ONOS by passing the uri of the device(s).
4151 Parameters:
4152 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4153 Returns:
4154 Returns main.FALSE if an exception is thrown or an error is present
4155 in the response. Otherwise, returns main.TRUE.
4156 NOTE:
4157 If a host cannot be removed, then this function will return main.FALSE
4158 '''
4159 try:
4160 if type( device ) is str:
4161 device = list( device )
4162
4163 for d in device:
4164 time.sleep( 1 )
4165 response = self.sendline( "device-remove {}".format( d ) )
4166 if "Error" in response:
4167 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4168 return main.FALSE
4169
4170 return main.TRUE
4171
4172 except TypeError:
4173 main.log.exception( self.name + ": Object not as expected" )
4174 return main.FALSE
4175 except pexpect.EOF:
4176 main.log.error( self.name + ": EOF exception found" )
4177 main.log.error( self.name + ": " + self.handle.before )
4178 main.cleanup()
4179 main.exit()
4180 except Exception:
4181 main.log.exception( self.name + ": Uncaught exception!" )
4182 main.cleanup()
4183 main.exit()
4184
4185 def removeHost( self, host ):
4186 '''
4187 Description:
4188 Remove a host from ONOS by passing the id of the host(s)
4189 Parameters:
4190 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4191 Returns:
4192 Returns main.FALSE if an exception is thrown or an error is present
4193 in the response. Otherwise, returns main.TRUE.
4194 NOTE:
4195 If a host cannot be removed, then this function will return main.FALSE
4196 '''
4197 try:
4198 if type( host ) is str:
4199 host = list( host )
4200
4201 for h in host:
4202 time.sleep( 1 )
4203 response = self.sendline( "host-remove {}".format( h ) )
4204 if "Error" in response:
4205 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4206 return main.FALSE
4207
4208 return main.TRUE
4209
4210 except TypeError:
4211 main.log.exception( self.name + ": Object not as expected" )
4212 return main.FALSE
4213 except pexpect.EOF:
4214 main.log.error( self.name + ": EOF exception found" )
4215 main.log.error( self.name + ": " + self.handle.before )
4216 main.cleanup()
4217 main.exit()
4218 except Exception:
4219 main.log.exception( self.name + ": Uncaught exception!" )
4220 main.cleanup()
4221 main.exit()