blob: 4f40b07533b8e7079dc2130ee5cb82e4fa6aa55d [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 sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
kelvin8ec71442015-01-15 16:57:00 -080022sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040023from drivers.common.clidriver import CLI
24
andrewonlab95ce8322014-10-13 14:12:04 -040025
kelvin8ec71442015-01-15 16:57:00 -080026class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028 def __init__( self ):
29 """
30 Initialize client
31 """
32 super( CLI, self ).__init__()
33
34 def connect( self, **connectargs ):
35 """
andrewonlab95ce8322014-10-13 14:12:04 -040036 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080037 """
andrewonlab95ce8322014-10-13 14:12:04 -040038 try:
39 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080040 vars( self )[ key ] = connectargs[ key ]
andrewonlab95ce8322014-10-13 14:12:04 -040041 self.home = "~/ONOS"
42 for key in self.options:
43 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080044 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040045 break
Jon Hallce9e5c42015-02-23 14:58:37 -080046 if self.home is None or self.home == "":
kelvin-onlabd6634ac2015-01-29 14:23:10 -080047 self.home = "~/ONOS"
Jon Hallce9e5c42015-02-23 14:58:37 -080048
kelvin8ec71442015-01-15 16:57:00 -080049 self.name = self.options[ 'name' ]
50 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080051 user_name=self.user_name,
52 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080053 port=self.port,
54 pwd=self.pwd,
55 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040056
kelvin8ec71442015-01-15 16:57:00 -080057 self.handle.sendline( "cd " + self.home )
58 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040059 if self.handle:
60 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080061 else:
62 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040063 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080064 except TypeError:
65 main.log.exception( self.name + ": Object not as expected" )
66 return None
andrewonlab95ce8322014-10-13 14:12:04 -040067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080068 main.log.error( self.name + ": EOF exception found" )
69 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040070 main.cleanup()
71 main.exit()
72 except:
Jon Halld4d4b372015-01-28 16:02:41 -080073 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040074 main.cleanup()
75 main.exit()
76
kelvin8ec71442015-01-15 16:57:00 -080077 def disconnect( self ):
78 """
andrewonlab95ce8322014-10-13 14:12:04 -040079 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080080 """
Jon Halld61331b2015-02-17 16:35:47 -080081 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040082 try:
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "" )
84 i = self.handle.expect( [ "onos>", "\$" ] )
Jon Hall7e5b9172014-10-22 12:32:47 -040085 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -080086 self.handle.sendline( "system:shutdown" )
87 self.handle.expect( "Confirm" )
88 self.handle.sendline( "yes" )
89 self.handle.expect( "\$" )
90 self.handle.sendline( "" )
91 self.handle.expect( "\$" )
92 self.handle.sendline( "exit" )
93 self.handle.expect( "closed" )
andrewonlabc2d05aa2014-10-13 16:51:10 -040094
Jon Halld4d4b372015-01-28 16:02:41 -080095 except TypeError:
96 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080097 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040098 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080099 main.log.error( self.name + ": EOF exception found" )
100 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400101 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800102 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 response = main.FALSE
104 return response
105
kelvin8ec71442015-01-15 16:57:00 -0800106 def logout( self ):
107 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500108 Sends 'logout' command to ONOS cli
kelvin8ec71442015-01-15 16:57:00 -0800109 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500110 try:
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle.sendline( "" )
112 i = self.handle.expect( [
andrewonlab9627f432014-11-14 12:45:10 -0500113 "onos>",
kelvin8ec71442015-01-15 16:57:00 -0800114 "\$" ], timeout=10 )
andrewonlab9627f432014-11-14 12:45:10 -0500115 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800116 self.handle.sendline( "logout" )
117 self.handle.expect( "\$" )
andrewonlab9627f432014-11-14 12:45:10 -0500118 elif i == 1:
119 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800120
Jon Halld4d4b372015-01-28 16:02:41 -0800121 except TypeError:
122 main.log.exception( self.name + ": Object not as expected" )
123 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500124 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800125 main.log.error( self.name + ": eof exception found" )
126 main.log.error( self.name + ": " +
127 self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500128 main.cleanup()
129 main.exit()
130 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800131 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 main.cleanup()
133 main.exit()
134
kelvin-onlabd3b64892015-01-20 13:26:24 -0800135 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800136 """
andrewonlab95ce8322014-10-13 14:12:04 -0400137 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800138
andrewonlab95ce8322014-10-13 14:12:04 -0400139 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800140 """
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
142 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800143 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400144 main.cleanup()
145 main.exit()
146 else:
kelvin8ec71442015-01-15 16:57:00 -0800147 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800148 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800149 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400150 # and that this driver will have to change accordingly
Jon Hall1e03cb62015-02-19 12:07:12 -0800151 self.handle.expect( "ONOS_CELL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800152 handleBefore = self.handle.before
153 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800154 # Get the rest of the handle
155 self.handle.sendline( "" )
156 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800157 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400158
kelvin-onlabd3b64892015-01-20 13:26:24 -0800159 main.log.info( "Cell call returned: " + handleBefore +
160 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400161
162 return main.TRUE
163
Jon Halld4d4b372015-01-28 16:02:41 -0800164 except TypeError:
165 main.log.exception( self.name + ": Object not as expected" )
166 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400167 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800168 main.log.error( self.name + ": eof exception found" )
169 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400170 main.cleanup()
171 main.exit()
172 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800173 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400174 main.cleanup()
175 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800176
kelvin-onlabd3b64892015-01-20 13:26:24 -0800177 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800178 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800179 karafTimeout is an optional arugument. karafTimeout value passed
180 by user would be used to set the current karaf shell idle timeout.
181 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800182 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800183 Below is an example to start a session with 60 seconds idle timeout
184 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800185
Hari Krishna25d42f72015-01-05 15:08:28 -0800186 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800187 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800188
kelvin-onlabd3b64892015-01-20 13:26:24 -0800189 Note: karafTimeout is left as str so that this could be read
190 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800191 """
andrewonlab95ce8322014-10-13 14:12:04 -0400192 try:
kelvin8ec71442015-01-15 16:57:00 -0800193 self.handle.sendline( "" )
194 x = self.handle.expect( [
195 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500196
197 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800198 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500199 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400200
kelvin8ec71442015-01-15 16:57:00 -0800201 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800202 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800203 i = self.handle.expect( [
204 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800205 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400206
207 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800208 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800209 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800210 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800211 "config:property-set -p org.apache.karaf.shell\
212 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800213 karafTimeout )
214 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800216 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400217 return main.TRUE
218 else:
kelvin8ec71442015-01-15 16:57:00 -0800219 # If failed, send ctrl+c to process and try again
220 main.log.info( "Starting CLI failed. Retrying..." )
221 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800223 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
224 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400225 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800227 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800228 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800229 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800230 "config:property-set -p org.apache.karaf.shell\
231 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800232 karafTimeout )
233 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800235 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400236 return main.TRUE
237 else:
kelvin8ec71442015-01-15 16:57:00 -0800238 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400240 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400241
Jon Halld4d4b372015-01-28 16:02:41 -0800242 except TypeError:
243 main.log.exception( self.name + ": Object not as expected" )
244 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400245 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800246 main.log.error( self.name + ": EOF exception found" )
247 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400248 main.cleanup()
249 main.exit()
250 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800251 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400252 main.cleanup()
253 main.exit()
254
kelvin-onlab338f5512015-02-06 10:53:16 -0800255 def log( self, cmdStr , level = "" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800256 """
257 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800258 returns main.TRUE on success
259 returns main.FALSE if Error occured
260 Available level: DEBUG, TRACE, INFO, WARN, ERROR
261 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800262 """
263 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800264 lvlStr = ""
265 if level:
266 lvlStr = "--level=" + level
267
kelvin-onlab9f541032015-02-04 16:19:53 -0800268 self.handle.sendline( "" )
269 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800270 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800271 self.handle.expect( "onos>" )
Jon Hallce9e5c42015-02-23 14:58:37 -0800272
kelvin-onlab9f541032015-02-04 16:19:53 -0800273 response = self.handle.before
274 if re.search( "Error", response ):
275 return main.FALSE
276 return main.TRUE
277
278 except pexpect.EOF:
279 main.log.error( self.name + ": EOF exception found" )
280 main.log.error( self.name + ": " + self.handle.before )
281 main.cleanup()
282 main.exit()
283 except:
Jon Hallce9e5c42015-02-23 14:58:37 -0800284 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800285 main.cleanup()
286 main.exit()
287
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800289 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800290 Send a completely user specified string to
291 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400292 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800293
andrewonlaba18f6bf2014-10-13 19:31:54 -0400294 Warning: There are no sanity checking to commands
295 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800296 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400297 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800298 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
299 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800300 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800301 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
302 response = self.handle.before
303 if i == 2:
304 self.handle.sendline()
305 self.handle.expect( "\$" )
306 response += self.handle.before
307 print response
308 try:
309 print self.handle.after
310 except:
311 pass
312 # TODO: do something with i
Jon Hallaea67aa2015-01-23 13:30:57 -0800313 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
314 + self.name + "." )
Jon Hall7bdfc122015-01-23 11:45:32 -0800315 # Remove control strings from output
316 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800317 response = ansiEscape.sub( '', response )
Jon Hallce9e5c42015-02-23 14:58:37 -0800318 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800319 response = re.sub( r"\s\r", "", response )
320 response = response.strip()
321 # parse for just the output, remove the cmd from response
322 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800323 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800324 except TypeError:
325 main.log.exception( self.name + ": Object not as expected" )
326 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400327 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800328 main.log.error( self.name + ": EOF exception found" )
329 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400330 main.cleanup()
331 main.exit()
332 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800333 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400334 main.cleanup()
335 main.exit()
336
kelvin8ec71442015-01-15 16:57:00 -0800337 # IMPORTANT NOTE:
338 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 # the cli command changing 'a:b' with 'aB'.
340 # Ex ) onos:topology > onosTopology
341 # onos:links > onosLinks
342 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800343
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800345 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400346 Adds a new cluster node by ID and address information.
347 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800348 * nodeId
349 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400350 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800351 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800352 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400353 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800354 cmdStr = "add-node " + str( nodeId ) + " " +\
355 str( ONOSIp ) + " " + str( tcpPort )
356 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800357 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800358 main.log.error( "Error in adding node" )
359 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800360 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400361 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800362 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400363 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800364 except TypeError:
365 main.log.exception( self.name + ": Object not as expected" )
366 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400367 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800368 main.log.error( self.name + ": EOF exception found" )
369 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400370 main.cleanup()
371 main.exit()
372 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800373 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400374 main.cleanup()
375 main.exit()
376
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800378 """
andrewonlab86dc3082014-10-13 18:18:38 -0400379 Removes a cluster by ID
380 Issues command: 'remove-node [<node-id>]'
381 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800382 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800383 """
andrewonlab86dc3082014-10-13 18:18:38 -0400384 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400385
kelvin-onlabd3b64892015-01-20 13:26:24 -0800386 cmdStr = "remove-node " + str( nodeId )
387 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800388 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400389
390 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800391
Jon Halld4d4b372015-01-28 16:02:41 -0800392 except TypeError:
393 main.log.exception( self.name + ": Object not as expected" )
394 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400395 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800396 main.log.error( self.name + ": EOF exception found" )
397 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400398 main.cleanup()
399 main.exit()
400 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800401 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400402 main.cleanup()
403 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400404
kelvin8ec71442015-01-15 16:57:00 -0800405 def nodes( self ):
406 """
andrewonlab7c211572014-10-15 16:45:20 -0400407 List the nodes currently visible
408 Issues command: 'nodes'
409 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800410 """
andrewonlab7c211572014-10-15 16:45:20 -0400411 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800412 cmdStr = "nodes"
413 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400414 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800415 except TypeError:
416 main.log.exception( self.name + ": Object not as expected" )
417 return None
andrewonlab7c211572014-10-15 16:45:20 -0400418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800419 main.log.error( self.name + ": EOF exception found" )
420 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400421 main.cleanup()
422 main.exit()
423 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800424 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400425 main.cleanup()
426 main.exit()
427
kelvin8ec71442015-01-15 16:57:00 -0800428 def topology( self ):
429 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400430 Shows the current state of the topology
431 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800432 """
andrewonlab95ce8322014-10-13 14:12:04 -0400433 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800434 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800435 cmdStr = "onos:topology"
436 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800437 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400438 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800439 except TypeError:
440 main.log.exception( self.name + ": Object not as expected" )
441 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400442 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800443 main.log.error( self.name + ": EOF exception found" )
444 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400445 main.cleanup()
446 main.exit()
447 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800448 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400449 main.cleanup()
450 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800451
kelvin-onlabd3b64892015-01-20 13:26:24 -0800452 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800453 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800454 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400455 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800458 cmdStr = "feature:install " + str( featureStr )
459 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800460 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400461 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800462 except TypeError:
463 main.log.exception( self.name + ": Object not as expected" )
464 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800466 main.log.error( self.name + ": EOF exception found" )
467 main.log.error( self.name + ": " + self.handle.before )
468 main.log.report( "Failed to install feature" )
469 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400470 main.cleanup()
471 main.exit()
472 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800473 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800474 main.log.report( "Failed to install feature" )
475 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400476 main.cleanup()
477 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800478
kelvin-onlabd3b64892015-01-20 13:26:24 -0800479 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800480 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400481 Uninstalls a specified feature
482 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800483 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400484 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 cmdStr = "feature:uninstall " + str( featureStr )
486 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800487 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400488 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800489 except TypeError:
490 main.log.exception( self.name + ": Object not as expected" )
491 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800493 main.log.error( self.name + ": EOF exception found" )
494 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400495 main.cleanup()
496 main.exit()
497 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800498 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400499 main.cleanup()
500 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800501
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800503 """
Jon Hall7b02d952014-10-17 20:14:54 -0400504 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400505 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800507 """
andrewonlab86dc3082014-10-13 18:18:38 -0400508 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 if jsonFormat:
510 cmdStr = "devices -j"
511 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800512 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800513 handle variable here contains some ANSI escape color code
514 sequences at the end which are invisible in the print command
515 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800516 function. The repr( handle ) output when printed shows the
517 ANSI escape sequences. In json.loads( somestring ), this
518 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800519 json.loads would fail with the escape sequence. So we take off
520 that escape sequence using:
521
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
523 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800524 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800525 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
526 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400527 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400528 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 cmdStr = "devices"
530 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400531 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800532 except TypeError:
533 main.log.exception( self.name + ": Object not as expected" )
534 return None
andrewonlab7c211572014-10-15 16:45:20 -0400535 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800536 main.log.error( self.name + ": EOF exception found" )
537 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400538 main.cleanup()
539 main.exit()
540 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800541 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400542 main.cleanup()
543 main.exit()
544
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800546 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800547 This balances the devices across all controllers
548 by issuing command: 'onos> onos:balance-masters'
549 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800550 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800551 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 cmdStr = "onos:balance-masters"
553 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800554 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800555 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800556 except TypeError:
557 main.log.exception( self.name + ": Object not as expected" )
558 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800562 main.cleanup()
563 main.exit()
564 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800565 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800566 main.cleanup()
567 main.exit()
568
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800570 """
Jon Halle8217482014-10-17 13:49:14 -0400571 Lists all core links
572 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800574 """
Jon Halle8217482014-10-17 13:49:14 -0400575 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 if jsonFormat:
577 cmdStr = "links -j"
578 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800579 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800580 handle variable here contains some ANSI escape color code
581 sequences at the end which are invisible in the print command
582 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800583 function. The repr( handle ) output when printed shows the ANSI
584 escape sequences. In json.loads( somestring ), this somestring
585 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800586 fail with the escape sequence. So we take off that escape
587 sequence using:
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
590 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800591 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
593 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400594 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400595 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 cmdStr = "links"
597 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400598 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800599 except TypeError:
600 main.log.exception( self.name + ": Object not as expected" )
601 return None
Jon Halle8217482014-10-17 13:49:14 -0400602 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800603 main.log.error( self.name + ": EOF exception found" )
604 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400605 main.cleanup()
606 main.exit()
607 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800608 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400609 main.cleanup()
610 main.exit()
611
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800613 """
Jon Halle8217482014-10-17 13:49:14 -0400614 Lists all ports
615 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800617 """
Jon Halle8217482014-10-17 13:49:14 -0400618 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 if jsonFormat:
620 cmdStr = "ports -j"
621 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800622 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800623 handle variable here contains some ANSI escape color code
624 sequences at the end which are invisible in the print command
625 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800626 function. The repr( handle ) output when printed shows the ANSI
627 escape sequences. In json.loads( somestring ), this somestring
628 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800629 fail with the escape sequence. So we take off that escape
630 sequence using the following commads:
631
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
633 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800634 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
636 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400637 return handle1
638
Jon Halle8217482014-10-17 13:49:14 -0400639 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 cmdStr = "ports"
641 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800642 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800643 except TypeError:
644 main.log.exception( self.name + ": Object not as expected" )
645 return None
Jon Halle8217482014-10-17 13:49:14 -0400646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800647 main.log.error( self.name + ": EOF exception found" )
648 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400649 main.cleanup()
650 main.exit()
651 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800652 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400653 main.cleanup()
654 main.exit()
655
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
Jon Hall983a1702014-10-28 18:44:22 -0400658 Lists all devices and the controllers with roles assigned to them
659 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800661 """
andrewonlab7c211572014-10-15 16:45:20 -0400662 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800663 if jsonFormat:
664 cmdStr = "roles -j"
665 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800666 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800667 handle variable here contains some ANSI escape color code
668 sequences at the end which are invisible in the print command
669 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800670 function. The repr( handle ) output when printed shows the ANSI
671 escape sequences. In json.loads( somestring ), this somestring
672 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800673 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500674
Jon Halle3f39ff2015-01-13 11:50:53 -0800675 So we take off that escape sequence using the following
676 commads:
677
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
679 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800680 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
682 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400683 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400684
andrewonlab7c211572014-10-15 16:45:20 -0400685 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 cmdStr = "roles"
687 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800688 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800689 except TypeError:
690 main.log.exception( self.name + ": Object not as expected" )
691 return None
Jon Hall983a1702014-10-28 18:44:22 -0400692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800693 main.log.error( self.name + ": EOF exception found" )
694 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400695 main.cleanup()
696 main.exit()
697 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800698 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400699 main.cleanup()
700 main.exit()
701
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800703 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800704 Given the a string containing the json representation of the "roles"
705 cli command and a partial or whole device id, returns a json object
706 containing the roles output for the first device whose id contains
707 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400708
709 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800710 A dict of the role assignments for the given device or
711 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800712 """
Jon Hall983a1702014-10-28 18:44:22 -0400713 try:
714 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400716 return None
717 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 rawRoles = self.roles()
719 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800720 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800722 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400724 return device
725 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800726 except TypeError:
727 main.log.exception( self.name + ": Object not as expected" )
728 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800730 main.log.error( self.name + ": EOF exception found" )
731 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400732 main.cleanup()
733 main.exit()
734 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800735 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400736 main.cleanup()
737 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall94fd0472014-12-08 11:52:42 -0800741 Iterates through each device and checks if there is a master assigned
742 Returns: main.TRUE if each device has a master
743 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800744 """
Jon Hall94fd0472014-12-08 11:52:42 -0800745 try:
746 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 rawRoles = self.roles()
748 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800749 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800751 # print device
752 if device[ 'master' ] == "none":
753 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800754 return main.FALSE
755 return main.TRUE
756
Jon Halld4d4b372015-01-28 16:02:41 -0800757 except TypeError:
758 main.log.exception( self.name + ": Object not as expected" )
759 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800760 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800763 main.cleanup()
764 main.exit()
765 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800766 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800767 main.cleanup()
768 main.exit()
769
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800771 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400772 Returns string of paths, and the cost.
773 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800774 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400775 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800776 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
777 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800778 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800779 main.log.error( "Error in getting paths" )
780 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400781 else:
kelvin8ec71442015-01-15 16:57:00 -0800782 path = handle.split( ";" )[ 0 ]
783 cost = handle.split( ";" )[ 1 ]
784 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800785 except TypeError:
786 main.log.exception( self.name + ": Object not as expected" )
787 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400788 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800789 main.log.error( self.name + ": EOF exception found" )
790 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400791 main.cleanup()
792 main.exit()
793 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800794 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400795 main.cleanup()
796 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800797
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800799 """
Jon Hallffb386d2014-11-21 13:43:38 -0800800 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400801 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800803 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400804 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 if jsonFormat:
806 cmdStr = "hosts -j"
807 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800808 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800809 handle variable here contains some ANSI escape color code
810 sequences at the end which are invisible in the print command
811 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800812 function. The repr( handle ) output when printed shows the ANSI
813 escape sequences. In json.loads( somestring ), this somestring
814 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800815 fail with the escape sequence. So we take off that escape
816 sequence using:
817
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
819 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800820 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
822 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400823 return handle1
824 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800825 cmdStr = "hosts"
826 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400827 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800828 except TypeError:
829 main.log.exception( self.name + ": Object not as expected" )
830 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400834 main.cleanup()
835 main.exit()
836 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800837 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400838 main.cleanup()
839 main.exit()
840
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800842 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400843 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800844
845 Note: mac must be a colon seperated mac address, but could be a
846 partial mac address
847
Jon Hall42db6dc2014-10-24 19:03:48 -0400848 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400850 import json
851 try:
kelvin8ec71442015-01-15 16:57:00 -0800852 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400853 return None
854 else:
855 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 rawHosts = self.hosts()
857 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800858 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800860 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800861 if not host:
862 pass
863 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400864 return host
865 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800866 except TypeError:
867 main.log.exception( self.name + ": Object not as expected" )
868 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400869 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800870 main.log.error( self.name + ": EOF exception found" )
871 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400872 main.cleanup()
873 main.exit()
874 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800875 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400876 main.cleanup()
877 main.exit()
878
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800880 """
881 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400882 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800883
andrewonlab3f0a4af2014-10-17 12:25:14 -0400884 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400886 IMPORTANT:
887 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800888 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400889 Furthermore, it assumes that value of VLAN is '-1'
890 Description:
kelvin8ec71442015-01-15 16:57:00 -0800891 Converts mininet hosts ( h1, h2, h3... ) into
892 ONOS format ( 00:00:00:00:00:01/-1 , ... )
893 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400894 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800898 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800899 hostHex = hex( int( host ) ).zfill( 12 )
900 hostHex = str( hostHex ).replace( 'x', '0' )
901 i = iter( str( hostHex ) )
902 hostHex = ":".join( a + b for a, b in zip( i, i ) )
903 hostHex = hostHex + "/-1"
904 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400905
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400907
Jon Halld4d4b372015-01-28 16:02:41 -0800908 except TypeError:
909 main.log.exception( self.name + ": Object not as expected" )
910 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400911 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800912 main.log.error( self.name + ": EOF exception found" )
913 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400914 main.cleanup()
915 main.exit()
916 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800917 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400918 main.cleanup()
919 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400920
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800922 """
andrewonlabe6745342014-10-17 14:29:13 -0400923 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 * hostIdOne: ONOS host id for host1
925 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400926 Description:
kelvin8ec71442015-01-15 16:57:00 -0800927 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500928 specifying the two hosts.
Jon Hallce9e5c42015-02-23 14:58:37 -0800929 Returns:
930 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800931 """
andrewonlabe6745342014-10-17 14:29:13 -0400932 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 cmdStr = "add-host-intent " + str( hostIdOne ) +\
934 " " + str( hostIdTwo )
935 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800936 if re.search( "Error", handle ):
937 main.log.error( "Error in adding Host intent" )
Jon Hallce9e5c42015-02-23 14:58:37 -0800938 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800939 else:
940 main.log.info( "Host intent installed between " +
Jon Hallce9e5c42015-02-23 14:58:37 -0800941 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jon Halla5cb6172015-02-23 09:28:28 -0800942 match = re.search('id=0x([\da-f]+),', handle)
943 if match:
944 return match.group()[3:-1]
945 else:
Jon Hallce9e5c42015-02-23 14:58:37 -0800946 main.log.error( "Error, intent ID not found" )
947 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800948 except TypeError:
949 main.log.exception( self.name + ": Object not as expected" )
950 return None
andrewonlabe6745342014-10-17 14:29:13 -0400951 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800952 main.log.error( self.name + ": EOF exception found" )
953 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400954 main.cleanup()
955 main.exit()
956 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800957 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400958 main.cleanup()
959 main.exit()
960
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800962 """
andrewonlab7b31d232014-10-24 13:31:47 -0400963 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 * ingressDevice: device id of ingress device
965 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400966 Optional:
967 TODO: Still needs to be implemented via dev side
Jon Hallce9e5c42015-02-23 14:58:37 -0800968 Description:
969 Adds an optical intent by specifying an ingress and egress device
970 Returns:
971 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800972 """
andrewonlab7b31d232014-10-24 13:31:47 -0400973 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
975 " " + str( egressDevice )
976 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800977 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800978 if re.search( "Error", handle ):
Jon Hallce9e5c42015-02-23 14:58:37 -0800979 main.log.error( "Error in adding Optical intent" )
980 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400981 else:
Jon Hallce9e5c42015-02-23 14:58:37 -0800982 main.log.info( "Optical intent installed between " +
983 str( ingressDevice ) + " and " +
984 str( egressDevice ) )
985 match = re.search('id=0x([\da-f]+),', handle)
986 if match:
987 return match.group()[3:-1]
988 else:
989 main.log.error( "Error, intent ID not found" )
990 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800991 except TypeError:
992 main.log.exception( self.name + ": Object not as expected" )
993 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400997 main.cleanup()
998 main.exit()
999 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001001 main.cleanup()
1002 main.exit()
1003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001005 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 ingressDevice,
1007 egressDevice,
1008 portIngress="",
1009 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001010 ethType="",
1011 ethSrc="",
1012 ethDst="",
1013 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001015 ipProto="",
1016 ipSrc="",
1017 ipDst="",
1018 tcpSrc="",
1019 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001020 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001021 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001022 * ingressDevice: device id of ingress device
1023 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001024 Optional:
1025 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001026 * ethSrc: specify ethSrc ( i.e. src mac addr )
1027 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001028 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001030 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001031 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001032 * ipSrc: specify ip source address
1033 * ipDst: specify ip destination address
1034 * tcpSrc: specify tcp source port
1035 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001036 Description:
kelvin8ec71442015-01-15 16:57:00 -08001037 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001038 specifying device id's and optional fields
Jon Hallce9e5c42015-02-23 14:58:37 -08001039 Returns:
1040 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001041
Jon Halle3f39ff2015-01-13 11:50:53 -08001042 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001043 options developers provide for point-to-point
1044 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001045 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001046 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001047 cmd = ""
1048
kelvin8ec71442015-01-15 16:57:00 -08001049 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001050 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001052 and not ipProto and not ipSrc and not ipDst \
1053 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001054 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001055
andrewonlab289e4b72014-10-21 21:24:18 -04001056 else:
andrewonlab36af3822014-11-18 17:48:18 -05001057 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001058
andrewonlab0c0a6772014-10-22 12:31:18 -04001059 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001060 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001061 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001062 cmd += " --ethSrc " + str( ethSrc )
1063 if ethDst:
1064 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001065 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001066 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001067 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001068 cmd += " --lambda "
1069 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001070 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001071 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001072 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001073 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001074 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001075 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001076 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001077 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001078 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001079
kelvin8ec71442015-01-15 16:57:00 -08001080 # Check whether the user appended the port
1081 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 if "/" in ingressDevice:
1083 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001084 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 if not portIngress:
Jon Hallce9e5c42015-02-23 14:58:37 -08001086 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001087 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001088 # Would it make sense to throw an exception and exit
1089 # the test?
1090 return None
andrewonlab36af3822014-11-18 17:48:18 -05001091
kelvin8ec71442015-01-15 16:57:00 -08001092 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 str( ingressDevice ) + "/" +\
1094 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 if "/" in egressDevice:
1097 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001098 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 if not portEgress:
Jon Hallce9e5c42015-02-23 14:58:37 -08001100 main.log.error( "You must specify the egress port" )
1101 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001102
kelvin8ec71442015-01-15 16:57:00 -08001103 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 str( egressDevice ) + "/" +\
1105 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001106
kelvin-onlab898a6c62015-01-16 14:13:53 -08001107 handle = self.sendline( cmd )
Jon Hallce9e5c42015-02-23 14:58:37 -08001108 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( "Error in adding point-to-point intent" )
Jon Hallce9e5c42015-02-23 14:58:37 -08001111 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001112 else:
Jon Hallce9e5c42015-02-23 14:58:37 -08001113 # TODO: print out all the options in this message?
1114 main.log.info( "Point-to-point intent installed between " +
1115 str( ingressDevice ) + " and " +
1116 str( egressDevice ) )
1117 match = re.search('id=0x([\da-f]+),', handle)
1118 if match:
1119 return match.group()[3:-1]
1120 else:
1121 main.log.error( "Error, intent ID not found" )
1122 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001123 except TypeError:
1124 main.log.exception( self.name + ": Object not as expected" )
1125 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001129 main.cleanup()
1130 main.exit()
1131 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001132 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001133 main.cleanup()
1134 main.exit()
1135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001137 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 ingressDevice1,
1139 ingressDevice2,
1140 egressDevice,
Jon Hallce9e5c42015-02-23 14:58:37 -08001141 portIngress1="",
1142 portIngress2="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001144 ethType="",
1145 ethSrc="",
1146 ethDst="",
1147 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001148 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001149 ipProto="",
1150 ipSrc="",
1151 ipDst="",
1152 tcpSrc="",
1153 tcpDst="",
1154 setEthSrc="",
1155 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001156 """
shahshreyad0c80432014-12-04 16:56:05 -08001157 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001158 This function assumes that there would be 2 ingress devices and
1159 one egress device. For more number of ingress devices, this
1160 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001161 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 * ingressDevice1: device id of ingress device1
1163 * ingressDevice2: device id of ingress device2
1164 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001165 Optional:
1166 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001167 * ethSrc: specify ethSrc ( i.e. src mac addr )
1168 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001169 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001171 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001172 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001173 * ipSrc: specify ip source address
1174 * ipDst: specify ip destination address
1175 * tcpSrc: specify tcp source port
1176 * tcpDst: specify tcp destination port
1177 * setEthSrc: action to Rewrite Source MAC Address
1178 * setEthDst: action to Rewrite Destination MAC Address
1179 Description:
kelvin8ec71442015-01-15 16:57:00 -08001180 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001181 specifying device id's and optional fields
Jon Hallce9e5c42015-02-23 14:58:37 -08001182 Returns:
1183 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001184
Jon Halle3f39ff2015-01-13 11:50:53 -08001185 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001186 options developers provide for multipointpoint-to-singlepoint
1187 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001188 """
shahshreyad0c80432014-12-04 16:56:05 -08001189 try:
1190 cmd = ""
1191
kelvin8ec71442015-01-15 16:57:00 -08001192 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001193 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001195 and not ipProto and not ipSrc and not ipDst\
1196 and not tcpSrc and not tcpDst and not setEthSrc\
1197 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001198 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001199
1200 else:
1201 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001202
shahshreyad0c80432014-12-04 16:56:05 -08001203 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001204 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001205 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001206 cmd += " --ethSrc " + str( ethSrc )
1207 if ethDst:
1208 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001209 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001210 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001212 cmd += " --lambda "
1213 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001214 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001215 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001217 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001218 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001219 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001220 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001221 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001222 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001223 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001224 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001225 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001226 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001227
kelvin8ec71442015-01-15 16:57:00 -08001228 # Check whether the user appended the port
1229 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 if "/" in ingressDevice1:
1231 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001232 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001234 main.log.error( "You must specify " +
1235 "the ingress port1" )
1236 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001237 return None
shahshreyad0c80432014-12-04 16:56:05 -08001238
kelvin8ec71442015-01-15 16:57:00 -08001239 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 str( ingressDevice1 ) + "/" +\
1241 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001242
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 if "/" in ingressDevice2:
1244 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001245 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001247 main.log.error( "You must specify " +
1248 "the ingress port2" )
1249 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001250 return None
shahshreyad0c80432014-12-04 16:56:05 -08001251
kelvin8ec71442015-01-15 16:57:00 -08001252 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 str( ingressDevice2 ) + "/" +\
1254 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001255
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 if "/" in egressDevice:
1257 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001258 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001260 main.log.error( "You must specify " +
1261 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001262 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001263
kelvin8ec71442015-01-15 16:57:00 -08001264 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 str( egressDevice ) + "/" +\
1266 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001267 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001268 handle = self.sendline( cmd )
Jon Hallce9e5c42015-02-23 14:58:37 -08001269 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 if re.search( "Error", handle ):
Jon Hallce9e5c42015-02-23 14:58:37 -08001271 main.log.error( "Error in adding multipoint-to-singlepoint " +
1272 "intent" )
1273 return None
shahshreyad0c80432014-12-04 16:56:05 -08001274 else:
Jon Hallce9e5c42015-02-23 14:58:37 -08001275 # TODO: print out all the options in this message?
1276 main.log.info( "Multipoint-to-singlepoint intent installed" +
1277 " between " + str( ingressDevice1 ) + ", " +
1278 str( ingressDevice2 ) + " and " +
1279 str( egressDevice ) )
1280 match = re.search('id=0x([\da-f]+),', handle)
1281 if match:
1282 return match.group()[3:-1]
1283 else:
1284 main.log.error( "Error, intent ID not found" )
1285 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001286 except TypeError:
1287 main.log.exception( self.name + ": Object not as expected" )
1288 return None
shahshreyad0c80432014-12-04 16:56:05 -08001289 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001290 main.log.error( self.name + ": EOF exception found" )
1291 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001292 main.cleanup()
1293 main.exit()
1294 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001295 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001296 main.cleanup()
1297 main.exit()
1298
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 def removeIntent( self, intentId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001300 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001301 Remove intent for specified intent id
Jon Halle3f39ff2015-01-13 11:50:53 -08001302
1303 Returns:
1304 main.False on error and
1305 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001306 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001307 try:
shahshreyac033d022015-02-20 16:10:19 -08001308 cmdStr = "remove-intent org.onosproject.cli " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001309 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001310 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001311 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001312 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001313 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001314 # TODO: Should this be main.TRUE
1315 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001316 except TypeError:
1317 main.log.exception( self.name + ": Object not as expected" )
1318 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001319 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001320 main.log.error( self.name + ": EOF exception found" )
1321 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001322 main.cleanup()
1323 main.exit()
1324 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001325 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001326 main.cleanup()
1327 main.exit()
1328
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001330 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001331 NOTE: This method should be used after installing application:
1332 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001333 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001334 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001335 Description:
1336 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001337 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001338 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001339 if jsonFormat:
1340 cmdStr = "routes -j"
1341 handleTmp = self.sendline( cmdStr )
1342 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1343 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001344 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001345 cmdStr = "routes"
1346 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001347 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001348 except TypeError:
1349 main.log.exception( self.name + ": Object not as expected" )
1350 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001351 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001352 main.log.error( self.name + ": EOF exception found" )
1353 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001354 main.cleanup()
1355 main.exit()
1356 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001357 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001358 main.cleanup()
1359 main.exit()
1360
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001362 """
andrewonlab377693f2014-10-21 16:00:30 -04001363 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001364 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001365 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001366 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001367 """
andrewonlabe6745342014-10-17 14:29:13 -04001368 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 if jsonFormat:
1370 cmdStr = "intents -j"
1371 handle = self.sendline( cmdStr )
1372 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1373 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001374 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 cmdStr = "intents"
1376 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001377 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001378 except TypeError:
1379 main.log.exception( self.name + ": Object not as expected" )
1380 return None
andrewonlabe6745342014-10-17 14:29:13 -04001381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001382 main.log.error( self.name + ": EOF exception found" )
1383 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001384 main.cleanup()
1385 main.exit()
1386 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001387 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001388 main.cleanup()
1389 main.exit()
1390
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001392 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001393 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001395 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001396 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001398 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 if jsonFormat:
1400 cmdStr = "flows -j"
1401 handle = self.sendline( cmdStr )
1402 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1403 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001404 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 cmdStr = "flows"
1406 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001407 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001408 main.log.error( self.name + ".flows() response: " +
1409 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001410 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001411 except TypeError:
1412 main.log.exception( self.name + ": Object not as expected" )
1413 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001414 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001415 main.log.error( self.name + ": EOF exception found" )
1416 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001417 main.cleanup()
1418 main.exit()
1419 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001420 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001421 main.cleanup()
1422 main.exit()
1423
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1425 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001426 """
andrewonlab87852b02014-11-19 18:44:19 -05001427 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001428 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001429 a specific point-to-point intent definition
1430 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 * dpidSrc: specify source dpid
1432 * dpidDst: specify destination dpid
1433 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001434 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001436 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001438 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001439 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001440 """
andrewonlab87852b02014-11-19 18:44:19 -05001441 try:
kelvin8ec71442015-01-15 16:57:00 -08001442 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1444 str( numIntents )
1445 if numMult:
1446 cmd += " " + str( numMult )
1447 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001448 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001449 if appId:
1450 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001451 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1453 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001454 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001456 main.log.info( handle )
1457 # Split result by newline
1458 newline = handle.split( "\r\r\n" )
1459 # Ignore the first object of list, which is empty
1460 newline = newline[ 1: ]
1461 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001462 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001463 result = result.split( ": " )
1464 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1466 main.log.info( latResult )
1467 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001468 else:
1469 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001470 except TypeError:
1471 main.log.exception( self.name + ": Object not as expected" )
1472 return None
andrewonlab87852b02014-11-19 18:44:19 -05001473 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001474 main.log.error( self.name + ": EOF exception found" )
1475 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001476 main.cleanup()
1477 main.exit()
1478 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001479 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001480 main.cleanup()
1481 main.exit()
1482
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001484 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001485 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001486 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001488 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001489 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 if jsonFormat:
1491 cmdStr = "intents-events-metrics -j"
1492 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001493 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1495 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001496 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 cmdStr = "intents-events-metrics"
1498 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001499 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001500 except TypeError:
1501 main.log.exception( self.name + ": Object not as expected" )
1502 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001503 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001504 main.log.error( self.name + ": EOF exception found" )
1505 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001506 main.cleanup()
1507 main.exit()
1508 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001509 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001510 main.cleanup()
1511 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001512
kelvin-onlabd3b64892015-01-20 13:26:24 -08001513 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001514 """
1515 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001516 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001518 """
andrewonlab867212a2014-10-22 20:13:38 -04001519 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001520 if jsonFormat:
1521 cmdStr = "topology-events-metrics -j"
1522 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001523 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1525 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001526 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 cmdStr = "topology-events-metrics"
1528 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001529 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001530 except TypeError:
1531 main.log.exception( self.name + ": Object not as expected" )
1532 return None
andrewonlab867212a2014-10-22 20:13:38 -04001533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001536 main.cleanup()
1537 main.exit()
1538 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001539 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001540 main.cleanup()
1541 main.exit()
1542
kelvin8ec71442015-01-15 16:57:00 -08001543 # Wrapper functions ****************
1544 # Wrapper functions use existing driver
1545 # functions and extends their use case.
1546 # For example, we may use the output of
1547 # a normal driver function, and parse it
1548 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001549
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001551 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001552 Description:
1553 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001554 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001555 try:
kelvin8ec71442015-01-15 16:57:00 -08001556 # Obtain output of intents function
Jon Halla5cb6172015-02-23 09:28:28 -08001557 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001559
kelvin8ec71442015-01-15 16:57:00 -08001560 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1562 for intents in intentsList:
Jon Halla5cb6172015-02-23 09:28:28 -08001563 match = re.search('id=0x([\da-f]+),', intents)
1564 if match:
1565 tmpId = match.group()[3:-1]
1566 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001568
Jon Halld4d4b372015-01-28 16:02:41 -08001569 except TypeError:
1570 main.log.exception( self.name + ": Object not as expected" )
1571 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001572 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001573 main.log.error( self.name + ": EOF exception found" )
1574 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001575 main.cleanup()
1576 main.exit()
1577 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001578 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001579 main.cleanup()
1580 main.exit()
1581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001583 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001584 Use 'devices' function to obtain list of all devices
1585 and parse the result to obtain a list of all device
1586 id's. Returns this list. Returns empty list if no
1587 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001588 List is ordered sequentially
1589
andrewonlab3e15ead2014-10-15 14:21:34 -04001590 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001591 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001592 the ids. By obtaining the list of device ids on the fly,
1593 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001594 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001595 try:
kelvin8ec71442015-01-15 16:57:00 -08001596 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 devicesStr = self.devices( jsonFormat=False )
1598 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001599
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001601 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 return idList
kelvin8ec71442015-01-15 16:57:00 -08001603
1604 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001606 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001608 # Split list further into arguments before and after string
1609 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 # append to idList
1611 for arg in tempList:
1612 idList.append( arg.split( "id=" )[ 1 ] )
1613 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001614
Jon Halld4d4b372015-01-28 16:02:41 -08001615 except TypeError:
1616 main.log.exception( self.name + ": Object not as expected" )
1617 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001618 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001619 main.log.error( self.name + ": EOF exception found" )
1620 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001621 main.cleanup()
1622 main.exit()
1623 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001624 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001625 main.cleanup()
1626 main.exit()
1627
kelvin-onlabd3b64892015-01-20 13:26:24 -08001628 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001629 """
andrewonlab7c211572014-10-15 16:45:20 -04001630 Uses 'nodes' function to obtain list of all nodes
1631 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001632 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001633 Returns:
1634 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001635 """
andrewonlab7c211572014-10-15 16:45:20 -04001636 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 nodesStr = self.nodes()
1638 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001639
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001641 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001643
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001645 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001646
kelvin8ec71442015-01-15 16:57:00 -08001647 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 nodesList = nodesStr.split( "," )
1649 tempList = [ node for node in nodesList if "id=" in node ]
1650 for arg in tempList:
1651 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001652
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 return idList
kelvin8ec71442015-01-15 16:57:00 -08001654
Jon Halld4d4b372015-01-28 16:02:41 -08001655 except TypeError:
1656 main.log.exception( self.name + ": Object not as expected" )
1657 return None
andrewonlab7c211572014-10-15 16:45:20 -04001658 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001659 main.log.error( self.name + ": EOF exception found" )
1660 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001661 main.cleanup()
1662 main.exit()
1663 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001664 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001665 main.cleanup()
1666 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001667
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001669 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001670 Return the first device from the devices api whose 'id' contains 'dpid'
1671 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001672 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001673 import json
1674 try:
kelvin8ec71442015-01-15 16:57:00 -08001675 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001676 return None
1677 else:
kelvin8ec71442015-01-15 16:57:00 -08001678 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 rawDevices = self.devices()
1680 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001681 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001683 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1684 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001685 return device
1686 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001687 except TypeError:
1688 main.log.exception( self.name + ": Object not as expected" )
1689 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001690 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001691 main.log.error( self.name + ": EOF exception found" )
1692 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001693 main.cleanup()
1694 main.exit()
1695 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001696 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001697 main.cleanup()
1698 main.exit()
1699
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001701 """
1702 Checks the number of swithes & links that ONOS sees against the
1703 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001704 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001705
Jon Hall42db6dc2014-10-24 19:03:48 -04001706 Params: ip = ip used for the onos cli
1707 numoswitch = expected number of switches
1708 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001709 logLevel = level to log to. Currently accepts
1710 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001711
1712
kelvin-onlabd3b64892015-01-20 13:26:24 -08001713 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001714
kelvin8ec71442015-01-15 16:57:00 -08001715 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001716 main.FALSE if the numer of switches and links is incorrect,
1717 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001718 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001719 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001720 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001721 if topology == {}:
1722 return main.ERROR
1723 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001724 # Is the number of switches is what we expected
1725 devices = topology.get( 'devices', False )
1726 links = topology.get( 'links', False )
Jon Hallce9e5c42015-02-23 14:58:37 -08001727 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001728 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001730 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 linkCheck = ( int( links ) == int( numolink ) )
1732 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001733 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001734 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001735 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001736 result = main.TRUE
1737 else:
1738 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001739 "The number of links and switches does not matc\
1740 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001741 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 output = output + "\n ONOS sees %i devices (%i expected) \
1743 and %i links (%i expected)" % (
1744 int( devices ), int( numoswitch ), int( links ),
1745 int( numolink ) )
1746 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001747 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001748 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001749 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001750 else:
kelvin8ec71442015-01-15 16:57:00 -08001751 main.log.info( output )
1752 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001753 except TypeError:
1754 main.log.exception( self.name + ": Object not as expected" )
1755 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001757 main.log.error( self.name + ": EOF exception found" )
1758 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001759 main.cleanup()
1760 main.exit()
1761 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001762 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001763 main.cleanup()
1764 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001765
kelvin-onlabd3b64892015-01-20 13:26:24 -08001766 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001767 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001768 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001769 deviceId must be the id of a device as seen in the onos devices command
1770 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001771 role must be either master, standby, or none
1772
Jon Halle3f39ff2015-01-13 11:50:53 -08001773 Returns:
1774 main.TRUE or main.FALSE based on argument verification and
1775 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001776 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001777 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001778 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001779 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001780 cmdStr = "device-role " +\
1781 str( deviceId ) + " " +\
1782 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001783 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001784 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001785 if re.search( "Error", handle ):
1786 # end color output to escape any colours
1787 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001788 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001789 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001790 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001791 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001792 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001793 main.log.error( "Invalid 'role' given to device_role(). " +
1794 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001795 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001796 except TypeError:
1797 main.log.exception( self.name + ": Object not as expected" )
1798 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001799 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001800 main.log.error( self.name + ": EOF exception found" )
1801 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001802 main.cleanup()
1803 main.exit()
1804 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001805 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001806 main.cleanup()
1807 main.exit()
1808
kelvin-onlabd3b64892015-01-20 13:26:24 -08001809 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001810 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001811 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001812 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001813 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001814 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001815 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001816 if jsonFormat:
1817 cmdStr = "clusters -j"
1818 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001819 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001820 handle variable here contains some ANSI escape color code
1821 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001822 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001823 function. The repr( handle ) output when printed shows the ANSI
1824 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001825 variable is actually repr( somestring ) and json.loads would
1826 fail with the escape sequence. So we take off that escape
1827 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001828
kelvin-onlabd3b64892015-01-20 13:26:24 -08001829 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1830 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001831 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1833 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001834 return handle1
1835 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001836 cmdStr = "clusters"
1837 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001838 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001839 except TypeError:
1840 main.log.exception( self.name + ": Object not as expected" )
1841 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001842 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001843 main.log.error( self.name + ": EOF exception found" )
1844 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001845 main.cleanup()
1846 main.exit()
1847 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001848 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001849 main.cleanup()
1850 main.exit()
1851
kelvin-onlabd3b64892015-01-20 13:26:24 -08001852 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001853 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001854 CLI command to get the current leader for the Election test application
1855 NOTE: Requires installation of the onos-app-election feature
1856 Returns: Node IP of the leader if one exists
1857 None if none exists
1858 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001859 """
Jon Hall94fd0472014-12-08 11:52:42 -08001860 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 cmdStr = "election-test-leader"
1862 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001863 # Leader
1864 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001865 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 nodeSearch = re.search( leaderPattern, response )
1867 if nodeSearch:
1868 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001869 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001871 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 # no leader
1873 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001874 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001875 nullSearch = re.search( nullPattern, response )
1876 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001877 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001878 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001879 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001880 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001881 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 if re.search( errorPattern, response ):
1883 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001884 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001885 return main.FALSE
1886 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001887 main.log.error( "Error in election_test_leader: " +
1888 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001889 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001890 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001891 except TypeError:
1892 main.log.exception( self.name + ": Object not as expected" )
1893 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001895 main.log.error( self.name + ": EOF exception found" )
1896 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001897 main.cleanup()
1898 main.exit()
1899 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001900 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001901 main.cleanup()
1902 main.exit()
1903
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001905 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 CLI command to run for leadership of the Election test application.
1907 NOTE: Requires installation of the onos-app-election feature
1908 Returns: Main.TRUE on success
1909 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001910 """
Jon Hall94fd0472014-12-08 11:52:42 -08001911 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001912 cmdStr = "election-test-run"
1913 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001914 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001915 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001916 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001917 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001918 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001919 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001920 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001921 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001922 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001923 errorPattern = "Command\snot\sfound"
1924 if re.search( errorPattern, response ):
1925 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001926 return main.FALSE
1927 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001928 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001929 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001930 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001931 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001932 except TypeError:
1933 main.log.exception( self.name + ": Object not as expected" )
1934 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001935 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001936 main.log.error( self.name + ": EOF exception found" )
1937 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001938 main.cleanup()
1939 main.exit()
1940 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001941 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001942 main.cleanup()
1943 main.exit()
1944
kelvin-onlabd3b64892015-01-20 13:26:24 -08001945 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001946 """
Jon Hall94fd0472014-12-08 11:52:42 -08001947 * CLI command to withdraw the local node from leadership election for
1948 * the Election test application.
1949 #NOTE: Requires installation of the onos-app-election feature
1950 Returns: Main.TRUE on success
1951 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001952 """
Jon Hall94fd0472014-12-08 11:52:42 -08001953 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001954 cmdStr = "election-test-withdraw"
1955 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001956 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001957 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001958 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001959 if re.search( successPattern, response ):
1960 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001961 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001962 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001963 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001964 errorPattern = "Command\snot\sfound"
1965 if re.search( errorPattern, response ):
1966 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001967 return main.FALSE
1968 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001969 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001970 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001971 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001972 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001976 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001979 main.cleanup()
1980 main.exit()
1981 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001982 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001983 main.cleanup()
1984 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001985
kelvin8ec71442015-01-15 16:57:00 -08001986 def getDevicePortsEnabledCount( self, dpid ):
1987 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001988 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001989 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001990 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001991 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001992 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1993 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001994 if re.search( "No such device", output ):
1995 main.log.error( "Error in getting ports" )
1996 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001997 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001998 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001999 except TypeError:
2000 main.log.exception( self.name + ": Object not as expected" )
2001 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002002 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002003 main.log.error( self.name + ": EOF exception found" )
2004 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002005 main.cleanup()
2006 main.exit()
2007 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002008 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002009 main.cleanup()
2010 main.exit()
2011
kelvin8ec71442015-01-15 16:57:00 -08002012 def getDeviceLinksActiveCount( self, dpid ):
2013 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002014 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002015 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002016 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002017 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002018 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2019 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002020 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002021 main.log.error( "Error in getting ports " )
2022 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002023 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002024 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002025 except TypeError:
2026 main.log.exception( self.name + ": Object not as expected" )
2027 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002029 main.log.error( self.name + ": EOF exception found" )
2030 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002031 main.cleanup()
2032 main.exit()
2033 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002034 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002035 main.cleanup()
2036 main.exit()
2037
kelvin8ec71442015-01-15 16:57:00 -08002038 def getAllIntentIds( self ):
2039 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002040 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002041 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002042 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002043 cmdStr = "onos:intents | grep id="
2044 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002045 if re.search( "Error", output ):
2046 main.log.error( "Error in getting ports" )
2047 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002048 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002049 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002050 except TypeError:
2051 main.log.exception( self.name + ": Object not as expected" )
2052 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002056 main.cleanup()
2057 main.exit()
2058 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002059 main.log.exception( self.name + ": Uncaught exception!" )
2060 main.cleanup()
2061 main.exit()
2062
Jon Hall63604932015-02-26 17:09:50 -08002063 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002064 """
Jon Hall63604932015-02-26 17:09:50 -08002065 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002066 """
Jon Halld4d4b372015-01-28 16:02:41 -08002067 try:
Jon Hall63604932015-02-26 17:09:50 -08002068 intents = self.intents( )
2069 intentStates = []
2070 for intent in json.loads( intents ): # Iter through intents of a node
2071 intentStates.append( intent.get( 'state', None ) )
2072 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2073 main.log.info( dict( out ) )
2074 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002075 except TypeError:
2076 main.log.exception( self.name + ": Object not as expected" )
2077 return None
2078 except pexpect.EOF:
2079 main.log.error( self.name + ": EOF exception found" )
2080 main.log.error( self.name + ": " + self.handle.before )
2081 main.cleanup()
2082 main.exit()
2083 except:
2084 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002085 main.cleanup()
2086 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002087
2088 def leaders( self ):
2089 """
2090 Returns the output of the leaders command.
2091 """
2092 # FIXME: add json output
2093 try:
2094 output = self.sendline( "onos:leaders" )
2095 main.log.warn( output )
2096 return output
2097 except TypeError:
2098 main.log.exception( self.name + ": Object not as expected" )
2099 return None
2100 except pexpect.EOF:
2101 main.log.error( self.name + ": EOF exception found" )
2102 main.log.error( self.name + ": " + self.handle.before )
2103 main.cleanup()
2104 main.exit()
2105 except:
2106 main.log.exception( self.name + ": Uncaught exception!" )
2107 main.cleanup()
2108 main.exit()
2109
2110 def pendingMap( self ):
2111 """
2112 Returns the output of the intent Pending map.
2113 """
2114 # FIXME: add json output
2115 try:
2116 output = self.sendline( "onos:intents -p" )
2117 main.log.warn( output )
2118 return output
2119 except TypeError:
2120 main.log.exception( self.name + ": Object not as expected" )
2121 return None
2122 except pexpect.EOF:
2123 main.log.error( self.name + ": EOF exception found" )
2124 main.log.error( self.name + ": " + self.handle.before )
2125 main.cleanup()
2126 main.exit()
2127 except:
2128 main.log.exception( self.name + ": Uncaught exception!" )
2129 main.cleanup()
2130 main.exit()
2131
2132 def partitions( self ):
2133 """
2134 Returns the output of the raft partitions command for ONOS.
2135 """
2136 # FIXME: add json output
2137 try:
2138 output = self.sendline( "partitions" )
2139 main.log.warn( output )
2140 return output
2141 except TypeError:
2142 main.log.exception( self.name + ": Object not as expected" )
2143 return None
2144 except pexpect.EOF:
2145 main.log.error( self.name + ": EOF exception found" )
2146 main.log.error( self.name + ": " + self.handle.before )
2147 main.cleanup()
2148 main.exit()
2149 except:
2150 main.log.exception( self.name + ": Uncaught exception!" )
2151 main.cleanup()
2152 main.exit()
2153