blob: 6b2335f352fdddb131e44295637ce176bf3e274b [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
Jon Hall3f45d112015-02-24 16:42:56 -080022import json
kelvin8ec71442015-01-15 16:57:00 -080023sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040024from drivers.common.clidriver import CLI
25
andrewonlab95ce8322014-10-13 14:12:04 -040026
Jon Hall3f45d112015-02-24 16:42:56 -080027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
34 super( CLI, self ).__init__()
35
36 def connect( self, **connectargs ):
37 """
andrewonlab95ce8322014-10-13 14:12:04 -040038 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080039 """
andrewonlab95ce8322014-10-13 14:12:04 -040040 try:
41 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080042 vars( self )[ key ] = connectargs[ key ]
andrewonlab95ce8322014-10-13 14:12:04 -040043 self.home = "~/ONOS"
44 for key in self.options:
45 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080046 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040047 break
kelvin-onlabd6634ac2015-01-29 14:23:10 -080048 if self.home == None or self.home == "":
49 self.home = "~/ONOS"
50
kelvin8ec71442015-01-15 16:57:00 -080051 self.name = self.options[ 'name' ]
52 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080053 user_name=self.user_name,
54 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080055 port=self.port,
56 pwd=self.pwd,
57 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040058
kelvin8ec71442015-01-15 16:57:00 -080059 self.handle.sendline( "cd " + self.home )
60 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040061 if self.handle:
62 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080063 else:
64 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080066 except TypeError:
67 main.log.exception( self.name + ": Object not as expected" )
68 return None
andrewonlab95ce8322014-10-13 14:12:04 -040069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080070 main.log.error( self.name + ": EOF exception found" )
71 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040072 main.cleanup()
73 main.exit()
74 except:
Jon Halld4d4b372015-01-28 16:02:41 -080075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
78
kelvin8ec71442015-01-15 16:57:00 -080079 def disconnect( self ):
80 """
andrewonlab95ce8322014-10-13 14:12:04 -040081 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080082 """
Jon Halld61331b2015-02-17 16:35:47 -080083 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040084 try:
Jon Hallb7fce3e2015-03-04 10:18:32 -080085 self.logout()
kelvin8ec71442015-01-15 16:57:00 -080086 self.handle.sendline( "" )
87 self.handle.expect( "\$" )
88 self.handle.sendline( "exit" )
89 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080092 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 except:
Jon Halld4d4b372015-01-28 16:02:41 -080097 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -040098 response = main.FALSE
99 return response
100
kelvin8ec71442015-01-15 16:57:00 -0800101 def logout( self ):
102 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500103 Sends 'logout' command to ONOS cli
kelvin8ec71442015-01-15 16:57:00 -0800104 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500105 try:
kelvin8ec71442015-01-15 16:57:00 -0800106 self.handle.sendline( "" )
Jon Hallb7fce3e2015-03-04 10:18:32 -0800107 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
108 timeout=10 )
109 if i == 0: # In ONOS CLI
kelvin8ec71442015-01-15 16:57:00 -0800110 self.handle.sendline( "logout" )
111 self.handle.expect( "\$" )
Jon Hallb7fce3e2015-03-04 10:18:32 -0800112 elif i == 1: # not in CLI
andrewonlab9627f432014-11-14 12:45:10 -0500113 return main.TRUE
Jon Hallb7fce3e2015-03-04 10:18:32 -0800114 elif i == 3: # Timeout
115 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
118 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": eof exception found" )
121 main.log.error( self.name + ": " +
122 self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500123 main.cleanup()
124 main.exit()
125 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500127 main.cleanup()
128 main.exit()
129
kelvin-onlabd3b64892015-01-20 13:26:24 -0800130 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800131 """
andrewonlab95ce8322014-10-13 14:12:04 -0400132 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800133
andrewonlab95ce8322014-10-13 14:12:04 -0400134 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800135 """
andrewonlab95ce8322014-10-13 14:12:04 -0400136 try:
137 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800138 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400139 main.cleanup()
140 main.exit()
141 else:
kelvin8ec71442015-01-15 16:57:00 -0800142 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800143 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800144 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400145 # and that this driver will have to change accordingly
Jon Hall1e03cb62015-02-19 12:07:12 -0800146 self.handle.expect( "ONOS_CELL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 handleBefore = self.handle.before
148 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800149 # Get the rest of the handle
150 self.handle.sendline( "" )
151 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800152 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400153
kelvin-onlabd3b64892015-01-20 13:26:24 -0800154 main.log.info( "Cell call returned: " + handleBefore +
155 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400156
157 return main.TRUE
158
Jon Halld4d4b372015-01-28 16:02:41 -0800159 except TypeError:
160 main.log.exception( self.name + ": Object not as expected" )
161 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400162 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800163 main.log.error( self.name + ": eof exception found" )
164 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400165 main.cleanup()
166 main.exit()
167 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800168 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400169 main.cleanup()
170 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800171
kelvin-onlabd3b64892015-01-20 13:26:24 -0800172 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800173 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800174 karafTimeout is an optional arugument. karafTimeout value passed
175 by user would be used to set the current karaf shell idle timeout.
176 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800177 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800178 Below is an example to start a session with 60 seconds idle timeout
179 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800180
Hari Krishna25d42f72015-01-05 15:08:28 -0800181 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800183
kelvin-onlabd3b64892015-01-20 13:26:24 -0800184 Note: karafTimeout is left as str so that this could be read
185 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 try:
kelvin8ec71442015-01-15 16:57:00 -0800188 self.handle.sendline( "" )
189 x = self.handle.expect( [
190 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500191
192 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500194 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400195
kelvin8ec71442015-01-15 16:57:00 -0800196 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800198 i = self.handle.expect( [
199 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800200 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400201
202 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800204 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800205 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800206 "config:property-set -p org.apache.karaf.shell\
207 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800208 karafTimeout )
209 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800210 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800211 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400212 return main.TRUE
213 else:
kelvin8ec71442015-01-15 16:57:00 -0800214 # If failed, send ctrl+c to process and try again
215 main.log.info( "Starting CLI failed. Retrying..." )
216 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800218 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
219 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400220 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800222 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400235 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400236
Jon Halld4d4b372015-01-28 16:02:41 -0800237 except TypeError:
238 main.log.exception( self.name + ": Object not as expected" )
239 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400240 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800241 main.log.error( self.name + ": EOF exception found" )
242 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400243 main.cleanup()
244 main.exit()
245 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800246 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400247 main.cleanup()
248 main.exit()
249
kelvin-onlab338f5512015-02-06 10:53:16 -0800250 def log( self, cmdStr , level = "" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800251 """
252 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800253 returns main.TRUE on success
254 returns main.FALSE if Error occured
255 Available level: DEBUG, TRACE, INFO, WARN, ERROR
256 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800257 """
258 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800259 lvlStr = ""
260 if level:
261 lvlStr = "--level=" + level
262
kelvin-onlab9f541032015-02-04 16:19:53 -0800263 self.handle.sendline( "" )
264 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800265 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800266 self.handle.expect( "onos>" )
267
268 response = self.handle.before
269 if re.search( "Error", response ):
270 return main.FALSE
271 return main.TRUE
272
273 except pexpect.EOF:
274 main.log.error( self.name + ": EOF exception found" )
275 main.log.error( self.name + ": " + self.handle.before )
276 main.cleanup()
277 main.exit()
278 except:
279 main.log.info( self.name + " ::::::" )
280 main.log.error( traceback.print_exc() )
281 main.log.info( self.name + " ::::::" )
282 main.cleanup()
283 main.exit()
284
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800286 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800287 Send a completely user specified string to
288 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400289 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800290
andrewonlaba18f6bf2014-10-13 19:31:54 -0400291 Warning: There are no sanity checking to commands
292 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800293 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400294 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800295
296 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
297 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
Jon Hallaea67aa2015-01-23 13:30:57 -0800300 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
301 + self.name + "." )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400302
303 handle = self.handle.before
Jon Hall7bdfc122015-01-23 11:45:32 -0800304 # Remove control strings from output
305 ansiEscape = re.compile( r'\x1b[^m]*m' )
306 handle = ansiEscape.sub( '', handle )
Jon Hall44225f82015-01-23 13:45:14 -0800307 #Remove extra return chars that get added
Jon Hallaea67aa2015-01-23 13:30:57 -0800308 handle = re.sub( r"\s\r", "", handle )
309 handle = handle.strip()
Jon Hall7bdfc122015-01-23 11:45:32 -0800310 # parse for just the output, remove the cmd from handle
311 output = handle.split( cmdStr, 1 )[1]
kelvin8ec71442015-01-15 16:57:00 -0800312
andrewonlaba18f6bf2014-10-13 19:31:54 -0400313
Jon Hall7bdfc122015-01-23 11:45:32 -0800314 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800315 except TypeError:
316 main.log.exception( self.name + ": Object not as expected" )
317 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400318 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800319 main.log.error( self.name + ": EOF exception found" )
320 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400321 main.cleanup()
322 main.exit()
323 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800324 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400325 main.cleanup()
326 main.exit()
327
kelvin8ec71442015-01-15 16:57:00 -0800328 # IMPORTANT NOTE:
329 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800330 # the cli command changing 'a:b' with 'aB'.
331 # Ex ) onos:topology > onosTopology
332 # onos:links > onosLinks
333 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800334
kelvin-onlabd3b64892015-01-20 13:26:24 -0800335 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800336 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400337 Adds a new cluster node by ID and address information.
338 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 * nodeId
340 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400341 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800342 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800343 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400344 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800345 cmdStr = "add-node " + str( nodeId ) + " " +\
346 str( ONOSIp ) + " " + str( tcpPort )
347 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800348 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800349 main.log.error( "Error in adding node" )
350 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800351 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400352 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800353 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400354 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800355 except TypeError:
356 main.log.exception( self.name + ": Object not as expected" )
357 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400358 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800359 main.log.error( self.name + ": EOF exception found" )
360 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400361 main.cleanup()
362 main.exit()
363 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800364 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400365 main.cleanup()
366 main.exit()
367
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800369 """
andrewonlab86dc3082014-10-13 18:18:38 -0400370 Removes a cluster by ID
371 Issues command: 'remove-node [<node-id>]'
372 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800373 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800374 """
andrewonlab86dc3082014-10-13 18:18:38 -0400375 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400376
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 cmdStr = "remove-node " + str( nodeId )
378 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800379 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400380
381 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800382
Jon Halld4d4b372015-01-28 16:02:41 -0800383 except TypeError:
384 main.log.exception( self.name + ": Object not as expected" )
385 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400386 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800387 main.log.error( self.name + ": EOF exception found" )
388 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400389 main.cleanup()
390 main.exit()
391 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800392 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400393 main.cleanup()
394 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400395
kelvin8ec71442015-01-15 16:57:00 -0800396 def nodes( self ):
397 """
andrewonlab7c211572014-10-15 16:45:20 -0400398 List the nodes currently visible
399 Issues command: 'nodes'
400 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800401 """
andrewonlab7c211572014-10-15 16:45:20 -0400402 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800403 cmdStr = "nodes"
404 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400405 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
andrewonlab7c211572014-10-15 16:45:20 -0400409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400412 main.cleanup()
413 main.exit()
414 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800415 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400416 main.cleanup()
417 main.exit()
418
kelvin8ec71442015-01-15 16:57:00 -0800419 def topology( self ):
420 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 Shows the current state of the topology
422 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlab95ce8322014-10-13 14:12:04 -0400424 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800425 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800426 cmdStr = "onos:topology"
427 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800428 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400429 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800430 except TypeError:
431 main.log.exception( self.name + ": Object not as expected" )
432 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400433 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800434 main.log.error( self.name + ": EOF exception found" )
435 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400436 main.cleanup()
437 main.exit()
438 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800439 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400440 main.cleanup()
441 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800442
kelvin-onlabd3b64892015-01-20 13:26:24 -0800443 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800444 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800445 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400448 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800449 cmdStr = "feature:install " + str( featureStr )
450 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800451 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400452 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800453 except TypeError:
454 main.log.exception( self.name + ": Object not as expected" )
455 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400456 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800457 main.log.error( self.name + ": EOF exception found" )
458 main.log.error( self.name + ": " + self.handle.before )
459 main.log.report( "Failed to install feature" )
460 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400461 main.cleanup()
462 main.exit()
463 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800464 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800465 main.log.report( "Failed to install feature" )
466 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400467 main.cleanup()
468 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800469
kelvin-onlabd3b64892015-01-20 13:26:24 -0800470 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800471 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400472 Uninstalls a specified feature
473 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800474 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400475 try:
shahshreya74cca802015-02-26 12:24:01 -0800476 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
477 handle = self.sendline( cmdStr )
shahshreya280223a2015-02-26 12:25:25 -0800478 if handle != '':
shahshreya74cca802015-02-26 12:24:01 -0800479 cmdStr = "feature:uninstall " + str( featureStr )
480 self.sendline( cmdStr )
481 # TODO: Check for possible error responses from karaf
shahshreya280223a2015-02-26 12:25:25 -0800482 else:
483 main.log.info( "Feature needs to be installed before uninstalling it" )
484 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800485 except TypeError:
486 main.log.exception( self.name + ": Object not as expected" )
487 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800489 main.log.error( self.name + ": EOF exception found" )
490 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400491 main.cleanup()
492 main.exit()
493 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800494 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400495 main.cleanup()
496 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800497
kelvin-onlabd3b64892015-01-20 13:26:24 -0800498 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800499 """
Jon Hall7b02d952014-10-17 20:14:54 -0400500 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400501 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800503 """
andrewonlab86dc3082014-10-13 18:18:38 -0400504 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 if jsonFormat:
506 cmdStr = "devices -j"
507 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800508 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800509 handle variable here contains some ANSI escape color code
510 sequences at the end which are invisible in the print command
511 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800512 function. The repr( handle ) output when printed shows the
513 ANSI escape sequences. In json.loads( somestring ), this
514 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800515 json.loads would fail with the escape sequence. So we take off
516 that escape sequence using:
517
kelvin-onlabd3b64892015-01-20 13:26:24 -0800518 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
519 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800520 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800521 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
522 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400523 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400524 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800525 cmdStr = "devices"
526 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400527 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800528 except TypeError:
529 main.log.exception( self.name + ": Object not as expected" )
530 return None
andrewonlab7c211572014-10-15 16:45:20 -0400531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800532 main.log.error( self.name + ": EOF exception found" )
533 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400534 main.cleanup()
535 main.exit()
536 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800537 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400538 main.cleanup()
539 main.exit()
540
kelvin-onlabd3b64892015-01-20 13:26:24 -0800541 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800542 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800543 This balances the devices across all controllers
544 by issuing command: 'onos> onos:balance-masters'
545 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800546 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800547 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 cmdStr = "onos:balance-masters"
549 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800550 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800551 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800552 except TypeError:
553 main.log.exception( self.name + ": Object not as expected" )
554 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800555 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800556 main.log.error( self.name + ": EOF exception found" )
557 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800558 main.cleanup()
559 main.exit()
560 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800561 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800562 main.cleanup()
563 main.exit()
564
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800566 """
Jon Halle8217482014-10-17 13:49:14 -0400567 Lists all core links
568 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800570 """
Jon Halle8217482014-10-17 13:49:14 -0400571 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800572 if jsonFormat:
573 cmdStr = "links -j"
574 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800575 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800576 handle variable here contains some ANSI escape color code
577 sequences at the end which are invisible in the print command
578 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800579 function. The repr( handle ) output when printed shows the ANSI
580 escape sequences. In json.loads( somestring ), this somestring
581 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800582 fail with the escape sequence. So we take off that escape
583 sequence using:
584
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
586 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800587 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
589 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400590 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400591 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "links"
593 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400594 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800595 except TypeError:
596 main.log.exception( self.name + ": Object not as expected" )
597 return None
Jon Halle8217482014-10-17 13:49:14 -0400598 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800599 main.log.error( self.name + ": EOF exception found" )
600 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400601 main.cleanup()
602 main.exit()
603 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800604 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400605 main.cleanup()
606 main.exit()
607
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800609 """
Jon Halle8217482014-10-17 13:49:14 -0400610 Lists all ports
611 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800613 """
Jon Halle8217482014-10-17 13:49:14 -0400614 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 if jsonFormat:
616 cmdStr = "ports -j"
617 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800618 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800619 handle variable here contains some ANSI escape color code
620 sequences at the end which are invisible in the print command
621 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800622 function. The repr( handle ) output when printed shows the ANSI
623 escape sequences. In json.loads( somestring ), this somestring
624 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800625 fail with the escape sequence. So we take off that escape
626 sequence using the following commads:
627
kelvin-onlabd3b64892015-01-20 13:26:24 -0800628 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
629 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800630 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800631 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
632 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400633 return handle1
634
Jon Halle8217482014-10-17 13:49:14 -0400635 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 cmdStr = "ports"
637 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800638 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
Jon Halle8217482014-10-17 13:49:14 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400645 main.cleanup()
646 main.exit()
647 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400649 main.cleanup()
650 main.exit()
651
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800653 """
Jon Hall983a1702014-10-28 18:44:22 -0400654 Lists all devices and the controllers with roles assigned to them
655 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 if jsonFormat:
660 cmdStr = "roles -j"
661 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800662 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800663 handle variable here contains some ANSI escape color code
664 sequences at the end which are invisible in the print command
665 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800666 function. The repr( handle ) output when printed shows the ANSI
667 escape sequences. In json.loads( somestring ), this somestring
668 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800669 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500670
Jon Halle3f39ff2015-01-13 11:50:53 -0800671 So we take off that escape sequence using the following
672 commads:
673
kelvin-onlabd3b64892015-01-20 13:26:24 -0800674 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
675 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800676 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
678 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400679 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400680
andrewonlab7c211572014-10-15 16:45:20 -0400681 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 cmdStr = "roles"
683 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800684 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800685 except TypeError:
686 main.log.exception( self.name + ": Object not as expected" )
687 return None
Jon Hall983a1702014-10-28 18:44:22 -0400688 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800689 main.log.error( self.name + ": EOF exception found" )
690 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400691 main.cleanup()
692 main.exit()
693 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800694 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400695 main.cleanup()
696 main.exit()
697
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800699 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800700 Given the a string containing the json representation of the "roles"
701 cli command and a partial or whole device id, returns a json object
702 containing the roles output for the first device whose id contains
703 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400704
705 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800706 A dict of the role assignments for the given device or
707 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Hall983a1702014-10-28 18:44:22 -0400709 try:
710 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400712 return None
713 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 rawRoles = self.roles()
715 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800716 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800718 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400720 return device
721 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800722 except TypeError:
723 main.log.exception( self.name + ": Object not as expected" )
724 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400725 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800726 main.log.error( self.name + ": EOF exception found" )
727 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400728 main.cleanup()
729 main.exit()
730 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800731 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400732 main.cleanup()
733 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800734
kelvin-onlabd3b64892015-01-20 13:26:24 -0800735 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800736 """
Jon Hall94fd0472014-12-08 11:52:42 -0800737 Iterates through each device and checks if there is a master assigned
738 Returns: main.TRUE if each device has a master
739 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall94fd0472014-12-08 11:52:42 -0800741 try:
742 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 rawRoles = self.roles()
744 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800745 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800747 # print device
748 if device[ 'master' ] == "none":
749 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800750 return main.FALSE
751 return main.TRUE
752
Jon Halld4d4b372015-01-28 16:02:41 -0800753 except TypeError:
754 main.log.exception( self.name + ": Object not as expected" )
755 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800757 main.log.error( self.name + ": EOF exception found" )
758 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800759 main.cleanup()
760 main.exit()
761 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800762 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800763 main.cleanup()
764 main.exit()
765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400768 Returns string of paths, and the cost.
769 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800770 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400771 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
773 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800774 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800775 main.log.error( "Error in getting paths" )
776 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400777 else:
kelvin8ec71442015-01-15 16:57:00 -0800778 path = handle.split( ";" )[ 0 ]
779 cost = handle.split( ";" )[ 1 ]
780 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800781 except TypeError:
782 main.log.exception( self.name + ": Object not as expected" )
783 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400784 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400787 main.cleanup()
788 main.exit()
789 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800790 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400791 main.cleanup()
792 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800793
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800795 """
Jon Hallffb386d2014-11-21 13:43:38 -0800796 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400797 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800799 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400800 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 if jsonFormat:
802 cmdStr = "hosts -j"
803 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800804 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800805 handle variable here contains some ANSI escape color code
806 sequences at the end which are invisible in the print command
807 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800808 function. The repr( handle ) output when printed shows the ANSI
809 escape sequences. In json.loads( somestring ), this somestring
810 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800811 fail with the escape sequence. So we take off that escape
812 sequence using:
813
kelvin-onlabd3b64892015-01-20 13:26:24 -0800814 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
815 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800816 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800817 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
818 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400819 return handle1
820 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 cmdStr = "hosts"
822 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400823 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800824 except TypeError:
825 main.log.exception( self.name + ": Object not as expected" )
826 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400827 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800828 main.log.error( self.name + ": EOF exception found" )
829 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400830 main.cleanup()
831 main.exit()
832 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800833 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400834 main.cleanup()
835 main.exit()
836
kelvin-onlabd3b64892015-01-20 13:26:24 -0800837 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800838 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400839 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800840
841 Note: mac must be a colon seperated mac address, but could be a
842 partial mac address
843
Jon Hall42db6dc2014-10-24 19:03:48 -0400844 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800845 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400846 import json
847 try:
kelvin8ec71442015-01-15 16:57:00 -0800848 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400849 return None
850 else:
851 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 rawHosts = self.hosts()
853 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800854 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800856 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800857 if not host:
858 pass
859 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400860 return host
861 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800862 except TypeError:
863 main.log.exception( self.name + ": Object not as expected" )
864 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400868 main.cleanup()
869 main.exit()
870 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800871 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400872 main.cleanup()
873 main.exit()
874
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800876 """
877 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400878 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800879
andrewonlab3f0a4af2014-10-17 12:25:14 -0400880 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800881 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400882 IMPORTANT:
883 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800884 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 Furthermore, it assumes that value of VLAN is '-1'
886 Description:
kelvin8ec71442015-01-15 16:57:00 -0800887 Converts mininet hosts ( h1, h2, h3... ) into
888 ONOS format ( 00:00:00:00:00:01/-1 , ... )
889 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400890 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800891 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400892
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800894 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 hostHex = hex( int( host ) ).zfill( 12 )
896 hostHex = str( hostHex ).replace( 'x', '0' )
897 i = iter( str( hostHex ) )
898 hostHex = ":".join( a + b for a, b in zip( i, i ) )
899 hostHex = hostHex + "/-1"
900 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400901
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400903
Jon Halld4d4b372015-01-28 16:02:41 -0800904 except TypeError:
905 main.log.exception( self.name + ": Object not as expected" )
906 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400910 main.cleanup()
911 main.exit()
912 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800913 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400914 main.cleanup()
915 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400916
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800918 """
andrewonlabe6745342014-10-17 14:29:13 -0400919 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 * hostIdOne: ONOS host id for host1
921 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400922 Description:
kelvin8ec71442015-01-15 16:57:00 -0800923 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500924 specifying the two hosts.
kelvin8ec71442015-01-15 16:57:00 -0800925 """
andrewonlabe6745342014-10-17 14:29:13 -0400926 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 cmdStr = "add-host-intent " + str( hostIdOne ) +\
928 " " + str( hostIdTwo )
929 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800930 if re.search( "Error", handle ):
931 main.log.error( "Error in adding Host intent" )
932 return handle
933 else:
934 main.log.info( "Host intent installed between " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800936 return main.TRUE
937
Jon Halld4d4b372015-01-28 16:02:41 -0800938 except TypeError:
939 main.log.exception( self.name + ": Object not as expected" )
940 return None
Hari Krishnaccfb0d52015-02-19 09:38:29 -0800941
andrewonlabe6745342014-10-17 14:29:13 -0400942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800943 main.log.error( self.name + ": EOF exception found" )
944 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400945 main.cleanup()
946 main.exit()
947 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800948 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400949 main.cleanup()
950 main.exit()
951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800953 """
andrewonlab7b31d232014-10-24 13:31:47 -0400954 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800955 * ingressDevice: device id of ingress device
956 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400957 Optional:
958 TODO: Still needs to be implemented via dev side
kelvin-onlab898a6c62015-01-16 14:13:53 -0800959 """
andrewonlab7b31d232014-10-24 13:31:47 -0400960 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
962 " " + str( egressDevice )
963 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800964 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800965 if re.search( "Error", handle ):
andrewonlab7b31d232014-10-24 13:31:47 -0400966 return handle
967 else:
968 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800969 except TypeError:
970 main.log.exception( self.name + ": Object not as expected" )
971 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400972 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800973 main.log.error( self.name + ": EOF exception found" )
974 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400975 main.cleanup()
976 main.exit()
977 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800978 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400979 main.cleanup()
980 main.exit()
981
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -0800983 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 ingressDevice,
985 egressDevice,
986 portIngress="",
987 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800988 ethType="",
989 ethSrc="",
990 ethDst="",
991 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800993 ipProto="",
994 ipSrc="",
995 ipDst="",
996 tcpSrc="",
997 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab4dbb4d82014-10-17 18:22:31 -0400999 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 * ingressDevice: device id of ingress device
1001 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001002 Optional:
1003 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001004 * ethSrc: specify ethSrc ( i.e. src mac addr )
1005 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001006 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001008 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001009 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001010 * ipSrc: specify ip source address
1011 * ipDst: specify ip destination address
1012 * tcpSrc: specify tcp source port
1013 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001014 Description:
kelvin8ec71442015-01-15 16:57:00 -08001015 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001016 specifying device id's and optional fields
1017
Jon Halle3f39ff2015-01-13 11:50:53 -08001018 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001019 options developers provide for point-to-point
1020 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001021 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001022 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001023 cmd = ""
1024
kelvin8ec71442015-01-15 16:57:00 -08001025 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001026 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001028 and not ipProto and not ipSrc and not ipDst \
1029 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001030 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001031
andrewonlab289e4b72014-10-21 21:24:18 -04001032 else:
andrewonlab36af3822014-11-18 17:48:18 -05001033 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001034
andrewonlab0c0a6772014-10-22 12:31:18 -04001035 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001036 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001037 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001038 cmd += " --ethSrc " + str( ethSrc )
1039 if ethDst:
1040 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001041 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001042 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001044 cmd += " --lambda "
1045 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001046 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001047 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001048 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001049 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001050 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001051 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001052 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001053 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001054 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001055
kelvin8ec71442015-01-15 16:57:00 -08001056 # Check whether the user appended the port
1057 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 if "/" in ingressDevice:
1059 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001060 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 if not portIngress:
kelvin8ec71442015-01-15 16:57:00 -08001062 main.log.error( "You must specify " +
1063 "the ingress port" )
1064 # TODO: perhaps more meaningful return
andrewonlab36af3822014-11-18 17:48:18 -05001065 return main.FALSE
1066
kelvin8ec71442015-01-15 16:57:00 -08001067 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 str( ingressDevice ) + "/" +\
1069 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001070
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 if "/" in egressDevice:
1072 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001073 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001075 main.log.error( "You must specify " +
1076 "the egress port" )
andrewonlab36af3822014-11-18 17:48:18 -05001077 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001078
kelvin8ec71442015-01-15 16:57:00 -08001079 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 str( egressDevice ) + "/" +\
1081 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001082
kelvin-onlab898a6c62015-01-16 14:13:53 -08001083 handle = self.sendline( cmd )
1084 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001085 main.log.error( "Error in adding point-to-point intent" )
Jon Hall47a93fb2015-01-06 16:46:06 -08001086 return main.FALSE
andrewonlab4dbb4d82014-10-17 18:22:31 -04001087 else:
1088 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001089 except TypeError:
1090 main.log.exception( self.name + ": Object not as expected" )
1091 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001093 main.log.error( self.name + ": EOF exception found" )
1094 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001095 main.cleanup()
1096 main.exit()
1097 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001098 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001099 main.cleanup()
1100 main.exit()
1101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001103 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 ingressDevice1,
1105 ingressDevice2,
1106 egressDevice,
1107 portIngress="",
1108 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 ethType="",
1110 ethSrc="",
1111 ethDst="",
1112 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001114 ipProto="",
1115 ipSrc="",
1116 ipDst="",
1117 tcpSrc="",
1118 tcpDst="",
1119 setEthSrc="",
1120 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001121 """
shahshreyad0c80432014-12-04 16:56:05 -08001122 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001123 This function assumes that there would be 2 ingress devices and
1124 one egress device. For more number of ingress devices, this
1125 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001126 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 * ingressDevice1: device id of ingress device1
1128 * ingressDevice2: device id of ingress device2
1129 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001130 Optional:
1131 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001132 * ethSrc: specify ethSrc ( i.e. src mac addr )
1133 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001134 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001136 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001137 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001138 * ipSrc: specify ip source address
1139 * ipDst: specify ip destination address
1140 * tcpSrc: specify tcp source port
1141 * tcpDst: specify tcp destination port
1142 * setEthSrc: action to Rewrite Source MAC Address
1143 * setEthDst: action to Rewrite Destination MAC Address
1144 Description:
kelvin8ec71442015-01-15 16:57:00 -08001145 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001146 specifying device id's and optional fields
1147
Jon Halle3f39ff2015-01-13 11:50:53 -08001148 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001149 options developers provide for multipointpoint-to-singlepoint
1150 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001151 """
shahshreyad0c80432014-12-04 16:56:05 -08001152 try:
1153 cmd = ""
1154
kelvin8ec71442015-01-15 16:57:00 -08001155 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001156 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001158 and not ipProto and not ipSrc and not ipDst\
1159 and not tcpSrc and not tcpDst and not setEthSrc\
1160 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001161 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001162
1163 else:
1164 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001165
shahshreyad0c80432014-12-04 16:56:05 -08001166 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001167 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001168 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001169 cmd += " --ethSrc " + str( ethSrc )
1170 if ethDst:
1171 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001172 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001173 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001175 cmd += " --lambda "
1176 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001177 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001178 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001180 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001181 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001182 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001184 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001186 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001188 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001190
kelvin8ec71442015-01-15 16:57:00 -08001191 # Check whether the user appended the port
1192 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 if "/" in ingressDevice1:
1194 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001195 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001197 main.log.error( "You must specify " +
1198 "the ingress port1" )
1199 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001200 return main.FALSE
1201
kelvin8ec71442015-01-15 16:57:00 -08001202 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 str( ingressDevice1 ) + "/" +\
1204 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001205
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 if "/" in ingressDevice2:
1207 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001208 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001210 main.log.error( "You must specify " +
1211 "the ingress port2" )
1212 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001213 return main.FALSE
1214
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 str( ingressDevice2 ) + "/" +\
1217 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001218
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 if "/" in egressDevice:
1220 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001221 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001223 main.log.error( "You must specify " +
1224 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001225 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001226
kelvin8ec71442015-01-15 16:57:00 -08001227 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001228 str( egressDevice ) + "/" +\
1229 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001230 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001231 handle = self.sendline( cmd )
1232 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( "Error in adding point-to-point intent" )
shahshreyad0c80432014-12-04 16:56:05 -08001234 return self.handle
1235 else:
1236 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001237 except TypeError:
1238 main.log.exception( self.name + ": Object not as expected" )
1239 return None
shahshreyad0c80432014-12-04 16:56:05 -08001240 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001243 main.cleanup()
1244 main.exit()
1245 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001246 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001247 main.cleanup()
1248 main.exit()
1249
shahshreya1c818fc2015-02-26 13:44:08 -08001250 def removeIntent( self, intentId, app = 'org.onosproject.cli',
1251 purge = False, sync = False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001252 """
shahshreya1c818fc2015-02-26 13:44:08 -08001253 Remove intent for specified application id and intent id
1254 Optional args:-
1255 -s or --sync: Waits for the removal before returning
1256 -p or --purge: Purge the intent from the store after removal
1257
Jon Halle3f39ff2015-01-13 11:50:53 -08001258 Returns:
1259 main.False on error and
1260 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001261 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001262 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001263 cmdStr = "remove-intent "
1264 if purge:
1265 cmdStr += " -p"
1266 if sync:
1267 cmdStr += " -s"
1268
1269 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001270 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001271 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001273 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001274 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001275 # TODO: Should this be main.TRUE
1276 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001277 except TypeError:
1278 main.log.exception( self.name + ": Object not as expected" )
1279 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001280 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001281 main.log.error( self.name + ": EOF exception found" )
1282 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001283 main.cleanup()
1284 main.exit()
1285 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001286 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001287 main.cleanup()
1288 main.exit()
1289
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001291 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001292 NOTE: This method should be used after installing application:
1293 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001294 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001295 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001296 Description:
1297 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001298 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001299 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 if jsonFormat:
1301 cmdStr = "routes -j"
1302 handleTmp = self.sendline( cmdStr )
1303 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1304 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001305 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001306 cmdStr = "routes"
1307 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001308 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001309 except TypeError:
1310 main.log.exception( self.name + ": Object not as expected" )
1311 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001312 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001313 main.log.error( self.name + ": EOF exception found" )
1314 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001315 main.cleanup()
1316 main.exit()
1317 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001318 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001319 main.cleanup()
1320 main.exit()
1321
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001323 """
andrewonlab377693f2014-10-21 16:00:30 -04001324 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001326 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001327 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001328 """
andrewonlabe6745342014-10-17 14:29:13 -04001329 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001330 if jsonFormat:
1331 cmdStr = "intents -j"
1332 handle = self.sendline( cmdStr )
1333 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1334 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001335 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 cmdStr = "intents"
1337 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001338 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001339 except TypeError:
1340 main.log.exception( self.name + ": Object not as expected" )
1341 return None
andrewonlabe6745342014-10-17 14:29:13 -04001342 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001343 main.log.error( self.name + ": EOF exception found" )
1344 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001345 main.cleanup()
1346 main.exit()
1347 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001348 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001349 main.cleanup()
1350 main.exit()
1351
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001353 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001354 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001356 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001357 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001358 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001359 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 if jsonFormat:
1361 cmdStr = "flows -j"
1362 handle = self.sendline( cmdStr )
1363 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1364 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001365 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001366 cmdStr = "flows"
1367 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001368 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 main.log.error( self.name + ".flows() response: " +
1370 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001371 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001372 except TypeError:
1373 main.log.exception( self.name + ": Object not as expected" )
1374 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001375 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001376 main.log.error( self.name + ": EOF exception found" )
1377 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001378 main.cleanup()
1379 main.exit()
1380 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001381 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001382 main.cleanup()
1383 main.exit()
1384
kelvin-onlabd3b64892015-01-20 13:26:24 -08001385 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1386 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001387 """
andrewonlab87852b02014-11-19 18:44:19 -05001388 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001389 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001390 a specific point-to-point intent definition
1391 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 * dpidSrc: specify source dpid
1393 * dpidDst: specify destination dpid
1394 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001395 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001397 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001399 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001400 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001401 """
andrewonlab87852b02014-11-19 18:44:19 -05001402 try:
kelvin8ec71442015-01-15 16:57:00 -08001403 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1405 str( numIntents )
1406 if numMult:
1407 cmd += " " + str( numMult )
1408 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001409 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 if appId:
1411 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001412 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1414 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001415 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001416 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001417 main.log.info( handle )
1418 # Split result by newline
1419 newline = handle.split( "\r\r\n" )
1420 # Ignore the first object of list, which is empty
1421 newline = newline[ 1: ]
1422 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001423 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001424 result = result.split( ": " )
1425 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1427 main.log.info( latResult )
1428 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001429 else:
1430 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001431 except TypeError:
1432 main.log.exception( self.name + ": Object not as expected" )
1433 return None
andrewonlab87852b02014-11-19 18:44:19 -05001434 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001435 main.log.error( self.name + ": EOF exception found" )
1436 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001437 main.cleanup()
1438 main.exit()
1439 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001440 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001441 main.cleanup()
1442 main.exit()
1443
kelvin-onlabd3b64892015-01-20 13:26:24 -08001444 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001445 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001447 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001448 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001449 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001450 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 if jsonFormat:
1452 cmdStr = "intents-events-metrics -j"
1453 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001454 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1456 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001457 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 cmdStr = "intents-events-metrics"
1459 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001460 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001461 except TypeError:
1462 main.log.exception( self.name + ": Object not as expected" )
1463 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001464 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001465 main.log.error( self.name + ": EOF exception found" )
1466 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001467 main.cleanup()
1468 main.exit()
1469 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001470 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001471 main.cleanup()
1472 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001473
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001475 """
1476 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001477 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001479 """
andrewonlab867212a2014-10-22 20:13:38 -04001480 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 if jsonFormat:
1482 cmdStr = "topology-events-metrics -j"
1483 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001484 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001485 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1486 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001487 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 cmdStr = "topology-events-metrics"
1489 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001490 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001491 except TypeError:
1492 main.log.exception( self.name + ": Object not as expected" )
1493 return None
andrewonlab867212a2014-10-22 20:13:38 -04001494 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001495 main.log.error( self.name + ": EOF exception found" )
1496 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001497 main.cleanup()
1498 main.exit()
1499 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001500 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001501 main.cleanup()
1502 main.exit()
1503
kelvin8ec71442015-01-15 16:57:00 -08001504 # Wrapper functions ****************
1505 # Wrapper functions use existing driver
1506 # functions and extends their use case.
1507 # For example, we may use the output of
1508 # a normal driver function, and parse it
1509 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001510
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001512 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001513 Description:
1514 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001515 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001516 try:
kelvin8ec71442015-01-15 16:57:00 -08001517 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 intentsStr = self.intents()
1519 allIntentList = []
1520 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001521
kelvin8ec71442015-01-15 16:57:00 -08001522 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1524 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001525 if "onos>" in intents:
1526 continue
1527 elif "intents" in intents:
1528 continue
1529 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 lineList = intents.split( " " )
1531 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001532
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001534
kelvin-onlabd3b64892015-01-20 13:26:24 -08001535 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001536 if not intents:
1537 continue
1538 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001540
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001542
Jon Halld4d4b372015-01-28 16:02:41 -08001543 except TypeError:
1544 main.log.exception( self.name + ": Object not as expected" )
1545 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001546 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001547 main.log.error( self.name + ": EOF exception found" )
1548 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001549 main.cleanup()
1550 main.exit()
1551 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001552 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001553 main.cleanup()
1554 main.exit()
1555
shahshreya353268a2015-02-25 17:03:41 -08001556
shahshreya580840d2015-02-26 10:44:04 -08001557 def FlowAddedCount( self, id ):
shahshreya353268a2015-02-25 17:03:41 -08001558 """
1559 Determine the number of flow rules for the given device id that are
1560 in the added state
1561 """
1562 try:
1563 cmdStr = "flows any " + id + " | grep 'state=ADDED' | wc -l"
1564 handle = self.sendline( cmdStr )
1565 return handle
1566 except pexpect.EOF:
1567 main.log.error( self.name + ": EOF exception found" )
1568 main.log.error( self.name + ": " + self.handle.before )
1569 main.cleanup()
1570 main.exit()
1571 except:
1572 main.log.exception( self.name + ": Uncaught exception!" )
1573 main.cleanup()
1574 main.exit()
1575
1576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001578 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001579 Use 'devices' function to obtain list of all devices
1580 and parse the result to obtain a list of all device
1581 id's. Returns this list. Returns empty list if no
1582 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001583 List is ordered sequentially
1584
andrewonlab3e15ead2014-10-15 14:21:34 -04001585 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001586 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001587 the ids. By obtaining the list of device ids on the fly,
1588 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001589 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001590 try:
kelvin8ec71442015-01-15 16:57:00 -08001591 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 devicesStr = self.devices( jsonFormat=False )
1593 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001594
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001596 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 return idList
kelvin8ec71442015-01-15 16:57:00 -08001598
1599 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001600 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001601 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001603 # Split list further into arguments before and after string
1604 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001605 # append to idList
1606 for arg in tempList:
1607 idList.append( arg.split( "id=" )[ 1 ] )
1608 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001609
Jon Halld4d4b372015-01-28 16:02:41 -08001610 except TypeError:
1611 main.log.exception( self.name + ": Object not as expected" )
1612 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001613 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001614 main.log.error( self.name + ": EOF exception found" )
1615 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001616 main.cleanup()
1617 main.exit()
1618 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001619 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001620 main.cleanup()
1621 main.exit()
1622
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001624 """
andrewonlab7c211572014-10-15 16:45:20 -04001625 Uses 'nodes' function to obtain list of all nodes
1626 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001627 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001628 Returns:
1629 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001630 """
andrewonlab7c211572014-10-15 16:45:20 -04001631 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 nodesStr = self.nodes()
1633 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001634
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001636 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001638
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001640 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001641
kelvin8ec71442015-01-15 16:57:00 -08001642 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 nodesList = nodesStr.split( "," )
1644 tempList = [ node for node in nodesList if "id=" in node ]
1645 for arg in tempList:
1646 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001647
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 return idList
kelvin8ec71442015-01-15 16:57:00 -08001649
Jon Halld4d4b372015-01-28 16:02:41 -08001650 except TypeError:
1651 main.log.exception( self.name + ": Object not as expected" )
1652 return None
andrewonlab7c211572014-10-15 16:45:20 -04001653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001654 main.log.error( self.name + ": EOF exception found" )
1655 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001656 main.cleanup()
1657 main.exit()
1658 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001659 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001660 main.cleanup()
1661 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001662
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001664 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001665 Return the first device from the devices api whose 'id' contains 'dpid'
1666 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001667 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001668 import json
1669 try:
kelvin8ec71442015-01-15 16:57:00 -08001670 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001671 return None
1672 else:
kelvin8ec71442015-01-15 16:57:00 -08001673 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 rawDevices = self.devices()
1675 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001676 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001678 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1679 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001680 return device
1681 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001682 except TypeError:
1683 main.log.exception( self.name + ": Object not as expected" )
1684 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001688 main.cleanup()
1689 main.exit()
1690 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001691 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001692 main.cleanup()
1693 main.exit()
1694
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001696 """
1697 Checks the number of swithes & links that ONOS sees against the
1698 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001699 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001700
Jon Hall42db6dc2014-10-24 19:03:48 -04001701 Params: ip = ip used for the onos cli
1702 numoswitch = expected number of switches
1703 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001704 logLevel = level to log to. Currently accepts
1705 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001706
1707
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001709
kelvin8ec71442015-01-15 16:57:00 -08001710 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001711 main.FALSE if the numer of switches and links is incorrect,
1712 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001713 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001714 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001715 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001716 if topology == {}:
1717 return main.ERROR
1718 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001719 # Is the number of switches is what we expected
1720 devices = topology.get( 'devices', False )
1721 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001722 if devices == False or links == False:
1723 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001725 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001726 linkCheck = ( int( links ) == int( numolink ) )
1727 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001728 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001729 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001730 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001731 result = main.TRUE
1732 else:
1733 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 "The number of links and switches does not matc\
1735 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001736 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001737 output = output + "\n ONOS sees %i devices (%i expected) \
1738 and %i links (%i expected)" % (
1739 int( devices ), int( numoswitch ), int( links ),
1740 int( numolink ) )
1741 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001742 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001744 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001745 else:
kelvin8ec71442015-01-15 16:57:00 -08001746 main.log.info( output )
1747 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001748 except TypeError:
1749 main.log.exception( self.name + ": Object not as expected" )
1750 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001751 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001752 main.log.error( self.name + ": EOF exception found" )
1753 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001754 main.cleanup()
1755 main.exit()
1756 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001757 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001758 main.cleanup()
1759 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001760
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001762 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001763 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001764 deviceId must be the id of a device as seen in the onos devices command
1765 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001766 role must be either master, standby, or none
1767
Jon Halle3f39ff2015-01-13 11:50:53 -08001768 Returns:
1769 main.TRUE or main.FALSE based on argument verification and
1770 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001771 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001772 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001773 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001774 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 cmdStr = "device-role " +\
1776 str( deviceId ) + " " +\
1777 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001780 if re.search( "Error", handle ):
1781 # end color output to escape any colours
1782 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001783 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001784 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001785 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001786 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001787 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001788 main.log.error( "Invalid 'role' given to device_role(). " +
1789 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001790 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001791 except TypeError:
1792 main.log.exception( self.name + ": Object not as expected" )
1793 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001794 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001795 main.log.error( self.name + ": EOF exception found" )
1796 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001797 main.cleanup()
1798 main.exit()
1799 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001800 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001801 main.cleanup()
1802 main.exit()
1803
kelvin-onlabd3b64892015-01-20 13:26:24 -08001804 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001805 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001806 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001807 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001808 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001809 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001810 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 if jsonFormat:
1812 cmdStr = "clusters -j"
1813 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001814 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001815 handle variable here contains some ANSI escape color code
1816 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001817 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001818 function. The repr( handle ) output when printed shows the ANSI
1819 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001820 variable is actually repr( somestring ) and json.loads would
1821 fail with the escape sequence. So we take off that escape
1822 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001823
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1825 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001826 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001827 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1828 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001829 return handle1
1830 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 cmdStr = "clusters"
1832 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001833 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001834 except TypeError:
1835 main.log.exception( self.name + ": Object not as expected" )
1836 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001837 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001838 main.log.error( self.name + ": EOF exception found" )
1839 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001840 main.cleanup()
1841 main.exit()
1842 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001843 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001844 main.cleanup()
1845 main.exit()
1846
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001849 CLI command to get the current leader for the Election test application
1850 NOTE: Requires installation of the onos-app-election feature
1851 Returns: Node IP of the leader if one exists
1852 None if none exists
1853 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001854 """
Jon Hall94fd0472014-12-08 11:52:42 -08001855 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001856 cmdStr = "election-test-leader"
1857 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001858 # Leader
1859 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001860 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001861 nodeSearch = re.search( leaderPattern, response )
1862 if nodeSearch:
1863 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001865 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001866 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001867 # no leader
1868 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001869 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 nullSearch = re.search( nullPattern, response )
1871 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001873 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001874 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001875 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001876 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001877 if re.search( errorPattern, response ):
1878 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001879 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001880 return main.FALSE
1881 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 main.log.error( "Error in election_test_leader: " +
1883 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001884 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001885 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001886 except TypeError:
1887 main.log.exception( self.name + ": Object not as expected" )
1888 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001890 main.log.error( self.name + ": EOF exception found" )
1891 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001892 main.cleanup()
1893 main.exit()
1894 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001895 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001896 main.cleanup()
1897 main.exit()
1898
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001900 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001901 CLI command to run for leadership of the Election test application.
1902 NOTE: Requires installation of the onos-app-election feature
1903 Returns: Main.TRUE on success
1904 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001905 """
Jon Hall94fd0472014-12-08 11:52:42 -08001906 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001907 cmdStr = "election-test-run"
1908 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001909 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001910 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001911 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001912 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001913 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001914 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001915 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001916 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001917 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001918 errorPattern = "Command\snot\sfound"
1919 if re.search( errorPattern, response ):
1920 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001921 return main.FALSE
1922 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001923 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001924 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001925 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001926 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001927 except TypeError:
1928 main.log.exception( self.name + ": Object not as expected" )
1929 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001931 main.log.error( self.name + ": EOF exception found" )
1932 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001933 main.cleanup()
1934 main.exit()
1935 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001936 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001937 main.cleanup()
1938 main.exit()
1939
kelvin-onlabd3b64892015-01-20 13:26:24 -08001940 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001941 """
Jon Hall94fd0472014-12-08 11:52:42 -08001942 * CLI command to withdraw the local node from leadership election for
1943 * the Election test application.
1944 #NOTE: Requires installation of the onos-app-election feature
1945 Returns: Main.TRUE on success
1946 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001947 """
Jon Hall94fd0472014-12-08 11:52:42 -08001948 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001949 cmdStr = "election-test-withdraw"
1950 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001951 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001952 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001953 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001954 if re.search( successPattern, response ):
1955 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001956 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001957 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001958 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001959 errorPattern = "Command\snot\sfound"
1960 if re.search( errorPattern, response ):
1961 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001962 return main.FALSE
1963 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001964 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001965 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001966 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001967 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001968 except TypeError:
1969 main.log.exception( self.name + ": Object not as expected" )
1970 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001971 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001972 main.log.error( self.name + ": EOF exception found" )
1973 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001974 main.cleanup()
1975 main.exit()
1976 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001977 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001978 main.cleanup()
1979 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001980
kelvin8ec71442015-01-15 16:57:00 -08001981 def getDevicePortsEnabledCount( self, dpid ):
1982 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001983 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001984 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001985 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001986 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001987 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1988 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001989 if re.search( "No such device", output ):
1990 main.log.error( "Error in getting ports" )
1991 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001992 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001993 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001994 except TypeError:
1995 main.log.exception( self.name + ": Object not as expected" )
1996 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001997 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001998 main.log.error( self.name + ": EOF exception found" )
1999 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002000 main.cleanup()
2001 main.exit()
2002 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002003 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002004 main.cleanup()
2005 main.exit()
2006
kelvin8ec71442015-01-15 16:57:00 -08002007 def getDeviceLinksActiveCount( self, dpid ):
2008 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002009 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002010 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002011 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002012 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002013 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2014 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002015 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002016 main.log.error( "Error in getting ports " )
2017 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002018 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002019 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002020 except TypeError:
2021 main.log.exception( self.name + ": Object not as expected" )
2022 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002024 main.log.error( self.name + ": EOF exception found" )
2025 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002026 main.cleanup()
2027 main.exit()
2028 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002029 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002030 main.cleanup()
2031 main.exit()
2032
kelvin8ec71442015-01-15 16:57:00 -08002033 def getAllIntentIds( self ):
2034 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002035 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002036 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002037 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 cmdStr = "onos:intents | grep id="
2039 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002040 if re.search( "Error", output ):
2041 main.log.error( "Error in getting ports" )
2042 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002043 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002044 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002045 except TypeError:
2046 main.log.exception( self.name + ": Object not as expected" )
2047 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002051 main.cleanup()
2052 main.exit()
2053 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002054 main.log.exception( self.name + ": Uncaught exception!" )
2055 main.cleanup()
2056 main.exit()
2057
Jon Hall3f45d112015-02-24 16:42:56 -08002058 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002059 """
Jon Hall3f45d112015-02-24 16:42:56 -08002060 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002061 """
Jon Halld4d4b372015-01-28 16:02:41 -08002062 try:
Jon Hall3f45d112015-02-24 16:42:56 -08002063 intents = self.intents( )
2064 intentStates = []
2065 out = []
2066 for intent in json.loads( intents ):
2067 intentStates.append( intent.get( 'state', None ) )
2068 for i in set( intentStates ):
2069 out.append( (i, intentStates.count( i ) ) )
2070 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002071 except TypeError:
2072 main.log.exception( self.name + ": Object not as expected" )
2073 return None
2074 except pexpect.EOF:
2075 main.log.error( self.name + ": EOF exception found" )
2076 main.log.error( self.name + ": " + self.handle.before )
2077 main.cleanup()
2078 main.exit()
2079 except:
2080 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002081 main.cleanup()
2082 main.exit()