blob: 3103772479e20157f5561ac7329aa7e7eab9f236 [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 )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
Jon Hallaea67aa2015-01-23 13:30:57 -0800302 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
303 + self.name + "." )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400304 handle = self.handle.before
Jon Hall7bdfc122015-01-23 11:45:32 -0800305 # Remove control strings from output
306 ansiEscape = re.compile( r'\x1b[^m]*m' )
307 handle = ansiEscape.sub( '', handle )
Jon Hallce9e5c42015-02-23 14:58:37 -0800308 # Remove extra return chars that get added
Jon Hallaea67aa2015-01-23 13:30:57 -0800309 handle = re.sub( r"\s\r", "", handle )
310 handle = handle.strip()
Jon Hall7bdfc122015-01-23 11:45:32 -0800311 # parse for just the output, remove the cmd from handle
312 output = handle.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800313 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800314 except TypeError:
315 main.log.exception( self.name + ": Object not as expected" )
316 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400317 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800318 main.log.error( self.name + ": EOF exception found" )
319 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400320 main.cleanup()
321 main.exit()
322 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800323 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400324 main.cleanup()
325 main.exit()
326
kelvin8ec71442015-01-15 16:57:00 -0800327 # IMPORTANT NOTE:
328 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800329 # the cli command changing 'a:b' with 'aB'.
330 # Ex ) onos:topology > onosTopology
331 # onos:links > onosLinks
332 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800333
kelvin-onlabd3b64892015-01-20 13:26:24 -0800334 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800335 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400336 Adds a new cluster node by ID and address information.
337 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800338 * nodeId
339 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400340 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800341 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800342 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400343 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 cmdStr = "add-node " + str( nodeId ) + " " +\
345 str( ONOSIp ) + " " + str( tcpPort )
346 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800347 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800348 main.log.error( "Error in adding node" )
349 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800350 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400351 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400353 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800354 except TypeError:
355 main.log.exception( self.name + ": Object not as expected" )
356 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400357 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800358 main.log.error( self.name + ": EOF exception found" )
359 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400360 main.cleanup()
361 main.exit()
362 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800363 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400364 main.cleanup()
365 main.exit()
366
kelvin-onlabd3b64892015-01-20 13:26:24 -0800367 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800368 """
andrewonlab86dc3082014-10-13 18:18:38 -0400369 Removes a cluster by ID
370 Issues command: 'remove-node [<node-id>]'
371 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800372 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800373 """
andrewonlab86dc3082014-10-13 18:18:38 -0400374 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400375
kelvin-onlabd3b64892015-01-20 13:26:24 -0800376 cmdStr = "remove-node " + str( nodeId )
377 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800378 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400379
380 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800381
Jon Halld4d4b372015-01-28 16:02:41 -0800382 except TypeError:
383 main.log.exception( self.name + ": Object not as expected" )
384 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400385 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800386 main.log.error( self.name + ": EOF exception found" )
387 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400388 main.cleanup()
389 main.exit()
390 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800391 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400392 main.cleanup()
393 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400394
kelvin8ec71442015-01-15 16:57:00 -0800395 def nodes( self ):
396 """
andrewonlab7c211572014-10-15 16:45:20 -0400397 List the nodes currently visible
398 Issues command: 'nodes'
399 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800400 """
andrewonlab7c211572014-10-15 16:45:20 -0400401 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800402 cmdStr = "nodes"
403 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400404 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800405 except TypeError:
406 main.log.exception( self.name + ": Object not as expected" )
407 return None
andrewonlab7c211572014-10-15 16:45:20 -0400408 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400411 main.cleanup()
412 main.exit()
413 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800414 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400415 main.cleanup()
416 main.exit()
417
kelvin8ec71442015-01-15 16:57:00 -0800418 def topology( self ):
419 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400420 Shows the current state of the topology
421 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800422 """
andrewonlab95ce8322014-10-13 14:12:04 -0400423 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800424 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 cmdStr = "onos:topology"
426 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800427 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400428 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800429 except TypeError:
430 main.log.exception( self.name + ": Object not as expected" )
431 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400432 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800433 main.log.error( self.name + ": EOF exception found" )
434 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400435 main.cleanup()
436 main.exit()
437 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800438 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400439 main.cleanup()
440 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800441
kelvin-onlabd3b64892015-01-20 13:26:24 -0800442 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800443 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800444 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800446 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400447 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800448 cmdStr = "feature:install " + str( featureStr )
449 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800450 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400451 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800452 except TypeError:
453 main.log.exception( self.name + ": Object not as expected" )
454 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400455 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800456 main.log.error( self.name + ": EOF exception found" )
457 main.log.error( self.name + ": " + self.handle.before )
458 main.log.report( "Failed to install feature" )
459 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400460 main.cleanup()
461 main.exit()
462 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800463 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800464 main.log.report( "Failed to install feature" )
465 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400466 main.cleanup()
467 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800470 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400471 Uninstalls a specified feature
472 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800473 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400474 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800475 cmdStr = "feature:uninstall " + str( featureStr )
476 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800477 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400478 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800479 except TypeError:
480 main.log.exception( self.name + ": Object not as expected" )
481 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400482 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800483 main.log.error( self.name + ": EOF exception found" )
484 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400485 main.cleanup()
486 main.exit()
487 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800488 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400489 main.cleanup()
490 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800491
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800493 """
Jon Hall7b02d952014-10-17 20:14:54 -0400494 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400495 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800496 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800497 """
andrewonlab86dc3082014-10-13 18:18:38 -0400498 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800499 if jsonFormat:
500 cmdStr = "devices -j"
501 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800502 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800503 handle variable here contains some ANSI escape color code
504 sequences at the end which are invisible in the print command
505 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800506 function. The repr( handle ) output when printed shows the
507 ANSI escape sequences. In json.loads( somestring ), this
508 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800509 json.loads would fail with the escape sequence. So we take off
510 that escape sequence using:
511
kelvin-onlabd3b64892015-01-20 13:26:24 -0800512 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
513 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800514 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
516 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400517 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400518 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 cmdStr = "devices"
520 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400521 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800522 except TypeError:
523 main.log.exception( self.name + ": Object not as expected" )
524 return None
andrewonlab7c211572014-10-15 16:45:20 -0400525 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800526 main.log.error( self.name + ": EOF exception found" )
527 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400528 main.cleanup()
529 main.exit()
530 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800531 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400532 main.cleanup()
533 main.exit()
534
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800536 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800537 This balances the devices across all controllers
538 by issuing command: 'onos> onos:balance-masters'
539 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800540 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800541 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800542 cmdStr = "onos:balance-masters"
543 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800544 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800545 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800546 except TypeError:
547 main.log.exception( self.name + ": Object not as expected" )
548 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800549 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800550 main.log.error( self.name + ": EOF exception found" )
551 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800552 main.cleanup()
553 main.exit()
554 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800555 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800556 main.cleanup()
557 main.exit()
558
kelvin-onlabd3b64892015-01-20 13:26:24 -0800559 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800560 """
Jon Halle8217482014-10-17 13:49:14 -0400561 Lists all core links
562 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800563 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800564 """
Jon Halle8217482014-10-17 13:49:14 -0400565 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800566 if jsonFormat:
567 cmdStr = "links -j"
568 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800569 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800570 handle variable here contains some ANSI escape color code
571 sequences at the end which are invisible in the print command
572 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800573 function. The repr( handle ) output when printed shows the ANSI
574 escape sequences. In json.loads( somestring ), this somestring
575 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800576 fail with the escape sequence. So we take off that escape
577 sequence using:
578
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
580 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800581 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
583 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400584 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400585 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 cmdStr = "links"
587 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400588 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800589 except TypeError:
590 main.log.exception( self.name + ": Object not as expected" )
591 return None
Jon Halle8217482014-10-17 13:49:14 -0400592 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800593 main.log.error( self.name + ": EOF exception found" )
594 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400595 main.cleanup()
596 main.exit()
597 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800598 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400599 main.cleanup()
600 main.exit()
601
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800603 """
Jon Halle8217482014-10-17 13:49:14 -0400604 Lists all ports
605 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800607 """
Jon Halle8217482014-10-17 13:49:14 -0400608 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800609 if jsonFormat:
610 cmdStr = "ports -j"
611 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800612 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800613 handle variable here contains some ANSI escape color code
614 sequences at the end which are invisible in the print command
615 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800616 function. The repr( handle ) output when printed shows the ANSI
617 escape sequences. In json.loads( somestring ), this somestring
618 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800619 fail with the escape sequence. So we take off that escape
620 sequence using the following commads:
621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
623 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800624 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
626 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400627 return handle1
628
Jon Halle8217482014-10-17 13:49:14 -0400629 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 cmdStr = "ports"
631 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800632 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800633 except TypeError:
634 main.log.exception( self.name + ": Object not as expected" )
635 return None
Jon Halle8217482014-10-17 13:49:14 -0400636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400639 main.cleanup()
640 main.exit()
641 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800642 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400643 main.cleanup()
644 main.exit()
645
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800647 """
Jon Hall983a1702014-10-28 18:44:22 -0400648 Lists all devices and the controllers with roles assigned to them
649 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800651 """
andrewonlab7c211572014-10-15 16:45:20 -0400652 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 if jsonFormat:
654 cmdStr = "roles -j"
655 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800656 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800657 handle variable here contains some ANSI escape color code
658 sequences at the end which are invisible in the print command
659 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800660 function. The repr( handle ) output when printed shows the ANSI
661 escape sequences. In json.loads( somestring ), this somestring
662 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800663 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500664
Jon Halle3f39ff2015-01-13 11:50:53 -0800665 So we take off that escape sequence using the following
666 commads:
667
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
669 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800670 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
672 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400673 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400674
andrewonlab7c211572014-10-15 16:45:20 -0400675 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 cmdStr = "roles"
677 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800678 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800679 except TypeError:
680 main.log.exception( self.name + ": Object not as expected" )
681 return None
Jon Hall983a1702014-10-28 18:44:22 -0400682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800683 main.log.error( self.name + ": EOF exception found" )
684 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400685 main.cleanup()
686 main.exit()
687 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800688 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400689 main.cleanup()
690 main.exit()
691
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800693 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800694 Given the a string containing the json representation of the "roles"
695 cli command and a partial or whole device id, returns a json object
696 containing the roles output for the first device whose id contains
697 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400698
699 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800700 A dict of the role assignments for the given device or
701 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800702 """
Jon Hall983a1702014-10-28 18:44:22 -0400703 try:
704 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400706 return None
707 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 rawRoles = self.roles()
709 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800710 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800712 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400714 return device
715 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800716 except TypeError:
717 main.log.exception( self.name + ": Object not as expected" )
718 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400719 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400722 main.cleanup()
723 main.exit()
724 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800725 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400726 main.cleanup()
727 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800728
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800730 """
Jon Hall94fd0472014-12-08 11:52:42 -0800731 Iterates through each device and checks if there is a master assigned
732 Returns: main.TRUE if each device has a master
733 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800734 """
Jon Hall94fd0472014-12-08 11:52:42 -0800735 try:
736 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 rawRoles = self.roles()
738 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800739 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800741 # print device
742 if device[ 'master' ] == "none":
743 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800744 return main.FALSE
745 return main.TRUE
746
Jon Halld4d4b372015-01-28 16:02:41 -0800747 except TypeError:
748 main.log.exception( self.name + ": Object not as expected" )
749 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800753 main.cleanup()
754 main.exit()
755 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800756 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800757 main.cleanup()
758 main.exit()
759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400762 Returns string of paths, and the cost.
763 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800764 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400765 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
767 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800768 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800769 main.log.error( "Error in getting paths" )
770 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400771 else:
kelvin8ec71442015-01-15 16:57:00 -0800772 path = handle.split( ";" )[ 0 ]
773 cost = handle.split( ";" )[ 1 ]
774 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800775 except TypeError:
776 main.log.exception( self.name + ": Object not as expected" )
777 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400778 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400781 main.cleanup()
782 main.exit()
783 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800784 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400785 main.cleanup()
786 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800787
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800789 """
Jon Hallffb386d2014-11-21 13:43:38 -0800790 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400791 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800792 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800793 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400794 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 if jsonFormat:
796 cmdStr = "hosts -j"
797 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800798 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800799 handle variable here contains some ANSI escape color code
800 sequences at the end which are invisible in the print command
801 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800802 function. The repr( handle ) output when printed shows the ANSI
803 escape sequences. In json.loads( somestring ), this somestring
804 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800805 fail with the escape sequence. So we take off that escape
806 sequence using:
807
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
809 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800810 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
812 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400813 return handle1
814 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800815 cmdStr = "hosts"
816 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400817 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800818 except TypeError:
819 main.log.exception( self.name + ": Object not as expected" )
820 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400821 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800822 main.log.error( self.name + ": EOF exception found" )
823 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400824 main.cleanup()
825 main.exit()
826 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800827 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400828 main.cleanup()
829 main.exit()
830
kelvin-onlabd3b64892015-01-20 13:26:24 -0800831 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800832 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400833 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800834
835 Note: mac must be a colon seperated mac address, but could be a
836 partial mac address
837
Jon Hall42db6dc2014-10-24 19:03:48 -0400838 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800839 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400840 import json
841 try:
kelvin8ec71442015-01-15 16:57:00 -0800842 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400843 return None
844 else:
845 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 rawHosts = self.hosts()
847 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800848 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800850 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800851 if not host:
852 pass
853 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400854 return host
855 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800856 except TypeError:
857 main.log.exception( self.name + ": Object not as expected" )
858 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400859 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800860 main.log.error( self.name + ": EOF exception found" )
861 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400862 main.cleanup()
863 main.exit()
864 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800865 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400866 main.cleanup()
867 main.exit()
868
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
871 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400872 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800873
andrewonlab3f0a4af2014-10-17 12:25:14 -0400874 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400876 IMPORTANT:
877 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800878 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400879 Furthermore, it assumes that value of VLAN is '-1'
880 Description:
kelvin8ec71442015-01-15 16:57:00 -0800881 Converts mininet hosts ( h1, h2, h3... ) into
882 ONOS format ( 00:00:00:00:00:01/-1 , ... )
883 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400884 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800885 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800888 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 hostHex = hex( int( host ) ).zfill( 12 )
890 hostHex = str( hostHex ).replace( 'x', '0' )
891 i = iter( str( hostHex ) )
892 hostHex = ":".join( a + b for a, b in zip( i, i ) )
893 hostHex = hostHex + "/-1"
894 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400897
Jon Halld4d4b372015-01-28 16:02:41 -0800898 except TypeError:
899 main.log.exception( self.name + ": Object not as expected" )
900 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400901 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800902 main.log.error( self.name + ": EOF exception found" )
903 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400904 main.cleanup()
905 main.exit()
906 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800907 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908 main.cleanup()
909 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400910
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800912 """
andrewonlabe6745342014-10-17 14:29:13 -0400913 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * hostIdOne: ONOS host id for host1
915 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400916 Description:
kelvin8ec71442015-01-15 16:57:00 -0800917 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500918 specifying the two hosts.
Jon Hallce9e5c42015-02-23 14:58:37 -0800919 Returns:
920 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800921 """
andrewonlabe6745342014-10-17 14:29:13 -0400922 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800923 cmdStr = "add-host-intent " + str( hostIdOne ) +\
924 " " + str( hostIdTwo )
925 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800926 if re.search( "Error", handle ):
927 main.log.error( "Error in adding Host intent" )
Jon Hallce9e5c42015-02-23 14:58:37 -0800928 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800929 else:
930 main.log.info( "Host intent installed between " +
Jon Hallce9e5c42015-02-23 14:58:37 -0800931 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jon Halla5cb6172015-02-23 09:28:28 -0800932 match = re.search('id=0x([\da-f]+),', handle)
933 if match:
934 return match.group()[3:-1]
935 else:
Jon Hallce9e5c42015-02-23 14:58:37 -0800936 main.log.error( "Error, intent ID not found" )
937 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800938 except TypeError:
939 main.log.exception( self.name + ": Object not as expected" )
940 return None
andrewonlabe6745342014-10-17 14:29:13 -0400941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800942 main.log.error( self.name + ": EOF exception found" )
943 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400944 main.cleanup()
945 main.exit()
946 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800947 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400948 main.cleanup()
949 main.exit()
950
kelvin-onlabd3b64892015-01-20 13:26:24 -0800951 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800952 """
andrewonlab7b31d232014-10-24 13:31:47 -0400953 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 * ingressDevice: device id of ingress device
955 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400956 Optional:
957 TODO: Still needs to be implemented via dev side
Jon Hallce9e5c42015-02-23 14:58:37 -0800958 Description:
959 Adds an optical intent by specifying an ingress and egress device
960 Returns:
961 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800962 """
andrewonlab7b31d232014-10-24 13:31:47 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
965 " " + str( egressDevice )
966 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800967 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800968 if re.search( "Error", handle ):
Jon Hallce9e5c42015-02-23 14:58:37 -0800969 main.log.error( "Error in adding Optical intent" )
970 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400971 else:
Jon Hallce9e5c42015-02-23 14:58:37 -0800972 main.log.info( "Optical intent installed between " +
973 str( ingressDevice ) + " and " +
974 str( egressDevice ) )
975 match = re.search('id=0x([\da-f]+),', handle)
976 if match:
977 return match.group()[3:-1]
978 else:
979 main.log.error( "Error, intent ID not found" )
980 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800981 except TypeError:
982 main.log.exception( self.name + ": Object not as expected" )
983 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400984 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800985 main.log.error( self.name + ": EOF exception found" )
986 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400987 main.cleanup()
988 main.exit()
989 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800990 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400991 main.cleanup()
992 main.exit()
993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -0800995 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 ingressDevice,
997 egressDevice,
998 portIngress="",
999 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001000 ethType="",
1001 ethSrc="",
1002 ethDst="",
1003 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001005 ipProto="",
1006 ipSrc="",
1007 ipDst="",
1008 tcpSrc="",
1009 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001010 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001011 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 * ingressDevice: device id of ingress device
1013 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001014 Optional:
1015 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001016 * ethSrc: specify ethSrc ( i.e. src mac addr )
1017 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001018 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001020 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001021 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001022 * ipSrc: specify ip source address
1023 * ipDst: specify ip destination address
1024 * tcpSrc: specify tcp source port
1025 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001026 Description:
kelvin8ec71442015-01-15 16:57:00 -08001027 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001028 specifying device id's and optional fields
Jon Hallce9e5c42015-02-23 14:58:37 -08001029 Returns:
1030 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001031
Jon Halle3f39ff2015-01-13 11:50:53 -08001032 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001033 options developers provide for point-to-point
1034 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001035 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001036 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001037 cmd = ""
1038
kelvin8ec71442015-01-15 16:57:00 -08001039 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001040 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001042 and not ipProto and not ipSrc and not ipDst \
1043 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001044 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001045
andrewonlab289e4b72014-10-21 21:24:18 -04001046 else:
andrewonlab36af3822014-11-18 17:48:18 -05001047 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001048
andrewonlab0c0a6772014-10-22 12:31:18 -04001049 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001050 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001051 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001052 cmd += " --ethSrc " + str( ethSrc )
1053 if ethDst:
1054 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001055 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001056 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001058 cmd += " --lambda "
1059 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001060 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001061 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001062 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001063 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001064 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001065 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001066 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001067 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001068 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001069
kelvin8ec71442015-01-15 16:57:00 -08001070 # Check whether the user appended the port
1071 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 if "/" in ingressDevice:
1073 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001074 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 if not portIngress:
Jon Hallce9e5c42015-02-23 14:58:37 -08001076 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001077 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001078 # Would it make sense to throw an exception and exit
1079 # the test?
1080 return None
andrewonlab36af3822014-11-18 17:48:18 -05001081
kelvin8ec71442015-01-15 16:57:00 -08001082 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 str( ingressDevice ) + "/" +\
1084 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 if "/" in egressDevice:
1087 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001088 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 if not portEgress:
Jon Hallce9e5c42015-02-23 14:58:37 -08001090 main.log.error( "You must specify the egress port" )
1091 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001092
kelvin8ec71442015-01-15 16:57:00 -08001093 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 str( egressDevice ) + "/" +\
1095 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001096
kelvin-onlab898a6c62015-01-16 14:13:53 -08001097 handle = self.sendline( cmd )
Jon Hallce9e5c42015-02-23 14:58:37 -08001098 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001099 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( "Error in adding point-to-point intent" )
Jon Hallce9e5c42015-02-23 14:58:37 -08001101 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001102 else:
Jon Hallce9e5c42015-02-23 14:58:37 -08001103 # TODO: print out all the options in this message?
1104 main.log.info( "Point-to-point intent installed between " +
1105 str( ingressDevice ) + " and " +
1106 str( egressDevice ) )
1107 match = re.search('id=0x([\da-f]+),', handle)
1108 if match:
1109 return match.group()[3:-1]
1110 else:
1111 main.log.error( "Error, intent ID not found" )
1112 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001113 except TypeError:
1114 main.log.exception( self.name + ": Object not as expected" )
1115 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001116 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001117 main.log.error( self.name + ": EOF exception found" )
1118 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001119 main.cleanup()
1120 main.exit()
1121 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001122 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001123 main.cleanup()
1124 main.exit()
1125
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001127 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 ingressDevice1,
1129 ingressDevice2,
1130 egressDevice,
Jon Hallce9e5c42015-02-23 14:58:37 -08001131 portIngress1="",
1132 portIngress2="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001134 ethType="",
1135 ethSrc="",
1136 ethDst="",
1137 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001138 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001139 ipProto="",
1140 ipSrc="",
1141 ipDst="",
1142 tcpSrc="",
1143 tcpDst="",
1144 setEthSrc="",
1145 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001146 """
shahshreyad0c80432014-12-04 16:56:05 -08001147 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001148 This function assumes that there would be 2 ingress devices and
1149 one egress device. For more number of ingress devices, this
1150 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001151 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001152 * ingressDevice1: device id of ingress device1
1153 * ingressDevice2: device id of ingress device2
1154 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001155 Optional:
1156 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001157 * ethSrc: specify ethSrc ( i.e. src mac addr )
1158 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001159 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001161 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001162 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001163 * ipSrc: specify ip source address
1164 * ipDst: specify ip destination address
1165 * tcpSrc: specify tcp source port
1166 * tcpDst: specify tcp destination port
1167 * setEthSrc: action to Rewrite Source MAC Address
1168 * setEthDst: action to Rewrite Destination MAC Address
1169 Description:
kelvin8ec71442015-01-15 16:57:00 -08001170 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001171 specifying device id's and optional fields
Jon Hallce9e5c42015-02-23 14:58:37 -08001172 Returns:
1173 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001174
Jon Halle3f39ff2015-01-13 11:50:53 -08001175 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001176 options developers provide for multipointpoint-to-singlepoint
1177 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001178 """
shahshreyad0c80432014-12-04 16:56:05 -08001179 try:
1180 cmd = ""
1181
kelvin8ec71442015-01-15 16:57:00 -08001182 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001183 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001185 and not ipProto and not ipSrc and not ipDst\
1186 and not tcpSrc and not tcpDst and not setEthSrc\
1187 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001188 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001189
1190 else:
1191 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001192
shahshreyad0c80432014-12-04 16:56:05 -08001193 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001194 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001195 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001196 cmd += " --ethSrc " + str( ethSrc )
1197 if ethDst:
1198 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001199 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001200 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001202 cmd += " --lambda "
1203 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001204 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001205 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001206 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001207 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001208 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001209 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001210 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001211 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001212 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001213 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001214 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001215 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001216 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001217
kelvin8ec71442015-01-15 16:57:00 -08001218 # Check whether the user appended the port
1219 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 if "/" in ingressDevice1:
1221 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001222 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( "You must specify " +
1225 "the ingress port1" )
1226 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001227 return None
shahshreyad0c80432014-12-04 16:56:05 -08001228
kelvin8ec71442015-01-15 16:57:00 -08001229 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 str( ingressDevice1 ) + "/" +\
1231 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 if "/" in ingressDevice2:
1234 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001235 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001237 main.log.error( "You must specify " +
1238 "the ingress port2" )
1239 # TODO: perhaps more meaningful return
Jon Hallce9e5c42015-02-23 14:58:37 -08001240 return None
shahshreyad0c80432014-12-04 16:56:05 -08001241
kelvin8ec71442015-01-15 16:57:00 -08001242 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 str( ingressDevice2 ) + "/" +\
1244 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001245
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 if "/" in egressDevice:
1247 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001248 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( "You must specify " +
1251 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001252 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001253
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 str( egressDevice ) + "/" +\
1256 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001257 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 handle = self.sendline( cmd )
Jon Hallce9e5c42015-02-23 14:58:37 -08001259 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001260 if re.search( "Error", handle ):
Jon Hallce9e5c42015-02-23 14:58:37 -08001261 main.log.error( "Error in adding multipoint-to-singlepoint " +
1262 "intent" )
1263 return None
shahshreyad0c80432014-12-04 16:56:05 -08001264 else:
Jon Hallce9e5c42015-02-23 14:58:37 -08001265 # TODO: print out all the options in this message?
1266 main.log.info( "Multipoint-to-singlepoint intent installed" +
1267 " between " + str( ingressDevice1 ) + ", " +
1268 str( ingressDevice2 ) + " and " +
1269 str( egressDevice ) )
1270 match = re.search('id=0x([\da-f]+),', handle)
1271 if match:
1272 return match.group()[3:-1]
1273 else:
1274 main.log.error( "Error, intent ID not found" )
1275 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001276 except TypeError:
1277 main.log.exception( self.name + ": Object not as expected" )
1278 return None
shahshreyad0c80432014-12-04 16:56:05 -08001279 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001280 main.log.error( self.name + ": EOF exception found" )
1281 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001282 main.cleanup()
1283 main.exit()
1284 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001285 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001286 main.cleanup()
1287 main.exit()
1288
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 def removeIntent( self, intentId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001290 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001291 Remove intent for specified intent id
Jon Halle3f39ff2015-01-13 11:50:53 -08001292
1293 Returns:
1294 main.False on error and
1295 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001296 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001297 try:
shahshreyac033d022015-02-20 16:10:19 -08001298 cmdStr = "remove-intent org.onosproject.cli " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001300 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001301 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001303 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001304 # TODO: Should this be main.TRUE
1305 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001306 except TypeError:
1307 main.log.exception( self.name + ": Object not as expected" )
1308 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( self.name + ": EOF exception found" )
1311 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001312 main.cleanup()
1313 main.exit()
1314 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001316 main.cleanup()
1317 main.exit()
1318
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001320 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001321 NOTE: This method should be used after installing application:
1322 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001323 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001324 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001325 Description:
1326 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001327 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001328 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 if jsonFormat:
1330 cmdStr = "routes -j"
1331 handleTmp = self.sendline( cmdStr )
1332 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1333 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001334 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 cmdStr = "routes"
1336 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001337 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001338 except TypeError:
1339 main.log.exception( self.name + ": Object not as expected" )
1340 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001341 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001342 main.log.error( self.name + ": EOF exception found" )
1343 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001344 main.cleanup()
1345 main.exit()
1346 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001347 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001348 main.cleanup()
1349 main.exit()
1350
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001352 """
andrewonlab377693f2014-10-21 16:00:30 -04001353 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001355 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001356 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001357 """
andrewonlabe6745342014-10-17 14:29:13 -04001358 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 if jsonFormat:
1360 cmdStr = "intents -j"
1361 handle = self.sendline( cmdStr )
1362 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1363 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001364 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 cmdStr = "intents"
1366 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001367 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001368 except TypeError:
1369 main.log.exception( self.name + ": Object not as expected" )
1370 return None
andrewonlabe6745342014-10-17 14:29:13 -04001371 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001372 main.log.error( self.name + ": EOF exception found" )
1373 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001374 main.cleanup()
1375 main.exit()
1376 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001377 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001378 main.cleanup()
1379 main.exit()
1380
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001382 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001383 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001385 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001386 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001387 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001388 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 if jsonFormat:
1390 cmdStr = "flows -j"
1391 handle = self.sendline( cmdStr )
1392 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1393 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001394 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 cmdStr = "flows"
1396 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001397 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 main.log.error( self.name + ".flows() response: " +
1399 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001400 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001401 except TypeError:
1402 main.log.exception( self.name + ": Object not as expected" )
1403 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001404 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001405 main.log.error( self.name + ": EOF exception found" )
1406 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001407 main.cleanup()
1408 main.exit()
1409 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001410 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001411 main.cleanup()
1412 main.exit()
1413
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1415 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001416 """
andrewonlab87852b02014-11-19 18:44:19 -05001417 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001418 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001419 a specific point-to-point intent definition
1420 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 * dpidSrc: specify source dpid
1422 * dpidDst: specify destination dpid
1423 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001424 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001425 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001426 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001428 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001429 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001430 """
andrewonlab87852b02014-11-19 18:44:19 -05001431 try:
kelvin8ec71442015-01-15 16:57:00 -08001432 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1434 str( numIntents )
1435 if numMult:
1436 cmd += " " + str( numMult )
1437 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001438 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 if appId:
1440 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001441 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1443 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001444 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001445 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001446 main.log.info( handle )
1447 # Split result by newline
1448 newline = handle.split( "\r\r\n" )
1449 # Ignore the first object of list, which is empty
1450 newline = newline[ 1: ]
1451 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001452 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001453 result = result.split( ": " )
1454 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1456 main.log.info( latResult )
1457 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001458 else:
1459 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001460 except TypeError:
1461 main.log.exception( self.name + ": Object not as expected" )
1462 return None
andrewonlab87852b02014-11-19 18:44:19 -05001463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001464 main.log.error( self.name + ": EOF exception found" )
1465 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001466 main.cleanup()
1467 main.exit()
1468 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001469 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001470 main.cleanup()
1471 main.exit()
1472
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001474 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001475 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001476 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001477 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001478 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001479 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 if jsonFormat:
1481 cmdStr = "intents-events-metrics -j"
1482 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001483 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1485 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001486 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 cmdStr = "intents-events-metrics"
1488 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001489 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001490 except TypeError:
1491 main.log.exception( self.name + ": Object not as expected" )
1492 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001493 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001494 main.log.error( self.name + ": EOF exception found" )
1495 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001496 main.cleanup()
1497 main.exit()
1498 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001499 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001500 main.cleanup()
1501 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001502
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001504 """
1505 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001506 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001508 """
andrewonlab867212a2014-10-22 20:13:38 -04001509 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 if jsonFormat:
1511 cmdStr = "topology-events-metrics -j"
1512 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001513 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001514 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1515 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001516 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001517 cmdStr = "topology-events-metrics"
1518 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001519 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001520 except TypeError:
1521 main.log.exception( self.name + ": Object not as expected" )
1522 return None
andrewonlab867212a2014-10-22 20:13:38 -04001523 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001524 main.log.error( self.name + ": EOF exception found" )
1525 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001526 main.cleanup()
1527 main.exit()
1528 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001529 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001530 main.cleanup()
1531 main.exit()
1532
kelvin8ec71442015-01-15 16:57:00 -08001533 # Wrapper functions ****************
1534 # Wrapper functions use existing driver
1535 # functions and extends their use case.
1536 # For example, we may use the output of
1537 # a normal driver function, and parse it
1538 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001539
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001541 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001542 Description:
1543 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001544 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001545 try:
kelvin8ec71442015-01-15 16:57:00 -08001546 # Obtain output of intents function
Jon Halla5cb6172015-02-23 09:28:28 -08001547 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001549
kelvin8ec71442015-01-15 16:57:00 -08001550 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1552 for intents in intentsList:
Jon Halla5cb6172015-02-23 09:28:28 -08001553 match = re.search('id=0x([\da-f]+),', intents)
1554 if match:
1555 tmpId = match.group()[3:-1]
1556 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001558
Jon Halld4d4b372015-01-28 16:02:41 -08001559 except TypeError:
1560 main.log.exception( self.name + ": Object not as expected" )
1561 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001562 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001563 main.log.error( self.name + ": EOF exception found" )
1564 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001565 main.cleanup()
1566 main.exit()
1567 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001568 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001569 main.cleanup()
1570 main.exit()
1571
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001573 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001574 Use 'devices' function to obtain list of all devices
1575 and parse the result to obtain a list of all device
1576 id's. Returns this list. Returns empty list if no
1577 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001578 List is ordered sequentially
1579
andrewonlab3e15ead2014-10-15 14:21:34 -04001580 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001581 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001582 the ids. By obtaining the list of device ids on the fly,
1583 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001584 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001585 try:
kelvin8ec71442015-01-15 16:57:00 -08001586 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 devicesStr = self.devices( jsonFormat=False )
1588 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001589
kelvin-onlabd3b64892015-01-20 13:26:24 -08001590 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001591 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 return idList
kelvin8ec71442015-01-15 16:57:00 -08001593
1594 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001596 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001598 # Split list further into arguments before and after string
1599 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 # append to idList
1601 for arg in tempList:
1602 idList.append( arg.split( "id=" )[ 1 ] )
1603 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001604
Jon Halld4d4b372015-01-28 16:02:41 -08001605 except TypeError:
1606 main.log.exception( self.name + ": Object not as expected" )
1607 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001609 main.log.error( self.name + ": EOF exception found" )
1610 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001611 main.cleanup()
1612 main.exit()
1613 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001614 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001615 main.cleanup()
1616 main.exit()
1617
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001619 """
andrewonlab7c211572014-10-15 16:45:20 -04001620 Uses 'nodes' function to obtain list of all nodes
1621 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001622 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001623 Returns:
1624 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001625 """
andrewonlab7c211572014-10-15 16:45:20 -04001626 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 nodesStr = self.nodes()
1628 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001629
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001631 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001633
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001635 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001636
kelvin8ec71442015-01-15 16:57:00 -08001637 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 nodesList = nodesStr.split( "," )
1639 tempList = [ node for node in nodesList if "id=" in node ]
1640 for arg in tempList:
1641 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001642
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 return idList
kelvin8ec71442015-01-15 16:57:00 -08001644
Jon Halld4d4b372015-01-28 16:02:41 -08001645 except TypeError:
1646 main.log.exception( self.name + ": Object not as expected" )
1647 return None
andrewonlab7c211572014-10-15 16:45:20 -04001648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001649 main.log.error( self.name + ": EOF exception found" )
1650 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001651 main.cleanup()
1652 main.exit()
1653 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001654 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001655 main.cleanup()
1656 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001657
kelvin-onlabd3b64892015-01-20 13:26:24 -08001658 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001659 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001660 Return the first device from the devices api whose 'id' contains 'dpid'
1661 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001662 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001663 import json
1664 try:
kelvin8ec71442015-01-15 16:57:00 -08001665 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001666 return None
1667 else:
kelvin8ec71442015-01-15 16:57:00 -08001668 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001669 rawDevices = self.devices()
1670 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001671 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001672 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001673 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1674 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001675 return device
1676 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001677 except TypeError:
1678 main.log.exception( self.name + ": Object not as expected" )
1679 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001680 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001681 main.log.error( self.name + ": EOF exception found" )
1682 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001683 main.cleanup()
1684 main.exit()
1685 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001686 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001687 main.cleanup()
1688 main.exit()
1689
kelvin-onlabd3b64892015-01-20 13:26:24 -08001690 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001691 """
1692 Checks the number of swithes & links that ONOS sees against the
1693 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001694 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001695
Jon Hall42db6dc2014-10-24 19:03:48 -04001696 Params: ip = ip used for the onos cli
1697 numoswitch = expected number of switches
1698 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001699 logLevel = level to log to. Currently accepts
1700 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001701
1702
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001704
kelvin8ec71442015-01-15 16:57:00 -08001705 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001706 main.FALSE if the numer of switches and links is incorrect,
1707 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001708 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001709 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001710 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001711 if topology == {}:
1712 return main.ERROR
1713 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001714 # Is the number of switches is what we expected
1715 devices = topology.get( 'devices', False )
1716 links = topology.get( 'links', False )
Jon Hallce9e5c42015-02-23 14:58:37 -08001717 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001718 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001719 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001720 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 linkCheck = ( int( links ) == int( numolink ) )
1722 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001723 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001724 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001725 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001726 result = main.TRUE
1727 else:
1728 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 "The number of links and switches does not matc\
1730 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001731 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 output = output + "\n ONOS sees %i devices (%i expected) \
1733 and %i links (%i expected)" % (
1734 int( devices ), int( numoswitch ), int( links ),
1735 int( numolink ) )
1736 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001737 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001739 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001740 else:
kelvin8ec71442015-01-15 16:57:00 -08001741 main.log.info( output )
1742 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001743 except TypeError:
1744 main.log.exception( self.name + ": Object not as expected" )
1745 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001746 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001747 main.log.error( self.name + ": EOF exception found" )
1748 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001749 main.cleanup()
1750 main.exit()
1751 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001752 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001753 main.cleanup()
1754 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001755
kelvin-onlabd3b64892015-01-20 13:26:24 -08001756 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001757 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001758 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001759 deviceId must be the id of a device as seen in the onos devices command
1760 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001761 role must be either master, standby, or none
1762
Jon Halle3f39ff2015-01-13 11:50:53 -08001763 Returns:
1764 main.TRUE or main.FALSE based on argument verification and
1765 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001766 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001767 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001768 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001769 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 cmdStr = "device-role " +\
1771 str( deviceId ) + " " +\
1772 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001773 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001774 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001775 if re.search( "Error", handle ):
1776 # end color output to escape any colours
1777 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001778 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001779 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001780 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001781 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001782 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001783 main.log.error( "Invalid 'role' given to device_role(). " +
1784 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001785 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001786 except TypeError:
1787 main.log.exception( self.name + ": Object not as expected" )
1788 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001789 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001790 main.log.error( self.name + ": EOF exception found" )
1791 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001792 main.cleanup()
1793 main.exit()
1794 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001795 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001796 main.cleanup()
1797 main.exit()
1798
kelvin-onlabd3b64892015-01-20 13:26:24 -08001799 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001800 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001801 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001802 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001803 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001804 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001805 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 if jsonFormat:
1807 cmdStr = "clusters -j"
1808 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001809 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001810 handle variable here contains some ANSI escape color code
1811 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001812 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001813 function. The repr( handle ) output when printed shows the ANSI
1814 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 variable is actually repr( somestring ) and json.loads would
1816 fail with the escape sequence. So we take off that escape
1817 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001818
kelvin-onlabd3b64892015-01-20 13:26:24 -08001819 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1820 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001821 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001822 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1823 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001824 return handle1
1825 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001826 cmdStr = "clusters"
1827 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001828 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001829 except TypeError:
1830 main.log.exception( self.name + ": Object not as expected" )
1831 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001833 main.log.error( self.name + ": EOF exception found" )
1834 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001835 main.cleanup()
1836 main.exit()
1837 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001838 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001839 main.cleanup()
1840 main.exit()
1841
kelvin-onlabd3b64892015-01-20 13:26:24 -08001842 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001843 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001844 CLI command to get the current leader for the Election test application
1845 NOTE: Requires installation of the onos-app-election feature
1846 Returns: Node IP of the leader if one exists
1847 None if none exists
1848 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
Jon Hall94fd0472014-12-08 11:52:42 -08001850 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001851 cmdStr = "election-test-leader"
1852 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001853 # Leader
1854 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001855 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 nodeSearch = re.search( leaderPattern, response )
1857 if nodeSearch:
1858 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001859 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001860 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001861 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 # no leader
1863 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001864 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001865 nullSearch = re.search( nullPattern, response )
1866 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001867 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001868 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001869 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 if re.search( errorPattern, response ):
1873 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001874 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001875 return main.FALSE
1876 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001877 main.log.error( "Error in election_test_leader: " +
1878 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001879 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001880 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001881 except TypeError:
1882 main.log.exception( self.name + ": Object not as expected" )
1883 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001884 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001885 main.log.error( self.name + ": EOF exception found" )
1886 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001887 main.cleanup()
1888 main.exit()
1889 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001890 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001891 main.cleanup()
1892 main.exit()
1893
kelvin-onlabd3b64892015-01-20 13:26:24 -08001894 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001895 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001896 CLI command to run for leadership of the Election test application.
1897 NOTE: Requires installation of the onos-app-election feature
1898 Returns: Main.TRUE on success
1899 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001900 """
Jon Hall94fd0472014-12-08 11:52:42 -08001901 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001902 cmdStr = "election-test-run"
1903 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001904 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001905 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001906 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001907 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001908 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001909 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001910 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001911 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001912 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001913 errorPattern = "Command\snot\sfound"
1914 if re.search( errorPattern, response ):
1915 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001916 return main.FALSE
1917 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001918 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001919 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001921 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001922 except TypeError:
1923 main.log.exception( self.name + ": Object not as expected" )
1924 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001926 main.log.error( self.name + ": EOF exception found" )
1927 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001928 main.cleanup()
1929 main.exit()
1930 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001931 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001932 main.cleanup()
1933 main.exit()
1934
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001936 """
Jon Hall94fd0472014-12-08 11:52:42 -08001937 * CLI command to withdraw the local node from leadership election for
1938 * the Election test application.
1939 #NOTE: Requires installation of the onos-app-election feature
1940 Returns: Main.TRUE on success
1941 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001942 """
Jon Hall94fd0472014-12-08 11:52:42 -08001943 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001944 cmdStr = "election-test-withdraw"
1945 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001946 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001947 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001948 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001949 if re.search( successPattern, response ):
1950 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001951 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001952 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001953 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001954 errorPattern = "Command\snot\sfound"
1955 if re.search( errorPattern, response ):
1956 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001957 return main.FALSE
1958 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001959 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001961 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001962 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001963 except TypeError:
1964 main.log.exception( self.name + ": Object not as expected" )
1965 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001966 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001967 main.log.error( self.name + ": EOF exception found" )
1968 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001969 main.cleanup()
1970 main.exit()
1971 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001972 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001973 main.cleanup()
1974 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001975
kelvin8ec71442015-01-15 16:57:00 -08001976 def getDevicePortsEnabledCount( self, dpid ):
1977 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001978 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001979 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001980 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001981 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001982 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1983 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001984 if re.search( "No such device", output ):
1985 main.log.error( "Error in getting ports" )
1986 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001987 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001988 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001989 except TypeError:
1990 main.log.exception( self.name + ": Object not as expected" )
1991 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001992 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001993 main.log.error( self.name + ": EOF exception found" )
1994 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001995 main.cleanup()
1996 main.exit()
1997 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001998 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001999 main.cleanup()
2000 main.exit()
2001
kelvin8ec71442015-01-15 16:57:00 -08002002 def getDeviceLinksActiveCount( self, dpid ):
2003 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002004 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002005 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002006 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002007 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2009 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002010 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002011 main.log.error( "Error in getting ports " )
2012 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002013 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002014 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002015 except TypeError:
2016 main.log.exception( self.name + ": Object not as expected" )
2017 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002018 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002019 main.log.error( self.name + ": EOF exception found" )
2020 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002021 main.cleanup()
2022 main.exit()
2023 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002024 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002025 main.cleanup()
2026 main.exit()
2027
kelvin8ec71442015-01-15 16:57:00 -08002028 def getAllIntentIds( self ):
2029 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002030 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002031 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002032 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 cmdStr = "onos:intents | grep id="
2034 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002035 if re.search( "Error", output ):
2036 main.log.error( "Error in getting ports" )
2037 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002038 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002039 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002040 except TypeError:
2041 main.log.exception( self.name + ": Object not as expected" )
2042 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002043 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002044 main.log.error( self.name + ": EOF exception found" )
2045 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002046 main.cleanup()
2047 main.exit()
2048 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002049 main.log.exception( self.name + ": Uncaught exception!" )
2050 main.cleanup()
2051 main.exit()
2052
2053 def testExceptions( self, obj ):
2054 """
2055 Test exception logging
2056 """
2057 # FIXME: Remove this before you commit
2058
2059 try:
2060 return obj[ 'dedf' ]
2061 except TypeError:
2062 main.log.exception( self.name + ": Object not as expected" )
2063 return None
2064 except pexpect.EOF:
2065 main.log.error( self.name + ": EOF exception found" )
2066 main.log.error( self.name + ": " + self.handle.before )
2067 main.cleanup()
2068 main.exit()
2069 except:
2070 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002071 main.cleanup()
2072 main.exit()