blob: aa91808484a20e181ff63aa959bf1c5554f913c8 [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:
kelvin8ec71442015-01-15 16:57:00 -080085 self.handle.sendline( "" )
86 i = self.handle.expect( [ "onos>", "\$" ] )
Jon Hall7e5b9172014-10-22 12:32:47 -040087 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -080088 self.handle.sendline( "system:shutdown" )
89 self.handle.expect( "Confirm" )
90 self.handle.sendline( "yes" )
91 self.handle.expect( "\$" )
92 self.handle.sendline( "" )
93 self.handle.expect( "\$" )
94 self.handle.sendline( "exit" )
95 self.handle.expect( "closed" )
andrewonlabc2d05aa2014-10-13 16:51:10 -040096
Jon Halld4d4b372015-01-28 16:02:41 -080097 except TypeError:
98 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080099 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800101 main.log.error( self.name + ": EOF exception found" )
102 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800104 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400105 response = main.FALSE
106 return response
107
kelvin8ec71442015-01-15 16:57:00 -0800108 def logout( self ):
109 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500110 Sends 'logout' command to ONOS cli
kelvin8ec71442015-01-15 16:57:00 -0800111 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500112 try:
kelvin8ec71442015-01-15 16:57:00 -0800113 self.handle.sendline( "" )
114 i = self.handle.expect( [
andrewonlab9627f432014-11-14 12:45:10 -0500115 "onos>",
kelvin8ec71442015-01-15 16:57:00 -0800116 "\$" ], timeout=10 )
andrewonlab9627f432014-11-14 12:45:10 -0500117 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "logout" )
119 self.handle.expect( "\$" )
andrewonlab9627f432014-11-14 12:45:10 -0500120 elif i == 1:
121 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800122
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
125 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": eof exception found" )
128 main.log.error( self.name + ": " +
129 self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500130 main.cleanup()
131 main.exit()
132 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500134 main.cleanup()
135 main.exit()
136
kelvin-onlabd3b64892015-01-20 13:26:24 -0800137 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800138 """
andrewonlab95ce8322014-10-13 14:12:04 -0400139 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800140
andrewonlab95ce8322014-10-13 14:12:04 -0400141 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800142 """
andrewonlab95ce8322014-10-13 14:12:04 -0400143 try:
144 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800145 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400146 main.cleanup()
147 main.exit()
148 else:
kelvin8ec71442015-01-15 16:57:00 -0800149 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800150 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800151 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400152 # and that this driver will have to change accordingly
Jon Hall1e03cb62015-02-19 12:07:12 -0800153 self.handle.expect( "ONOS_CELL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800154 handleBefore = self.handle.before
155 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800156 # Get the rest of the handle
157 self.handle.sendline( "" )
158 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800159 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400160
kelvin-onlabd3b64892015-01-20 13:26:24 -0800161 main.log.info( "Cell call returned: " + handleBefore +
162 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400163
164 return main.TRUE
165
Jon Halld4d4b372015-01-28 16:02:41 -0800166 except TypeError:
167 main.log.exception( self.name + ": Object not as expected" )
168 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": eof exception found" )
171 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400172 main.cleanup()
173 main.exit()
174 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800175 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400176 main.cleanup()
177 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800178
kelvin-onlabd3b64892015-01-20 13:26:24 -0800179 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800180 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800181 karafTimeout is an optional arugument. karafTimeout value passed
182 by user would be used to set the current karaf shell idle timeout.
183 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800184 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 Below is an example to start a session with 60 seconds idle timeout
186 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800187
Hari Krishna25d42f72015-01-05 15:08:28 -0800188 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800189 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800190
kelvin-onlabd3b64892015-01-20 13:26:24 -0800191 Note: karafTimeout is left as str so that this could be read
192 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800193 """
andrewonlab95ce8322014-10-13 14:12:04 -0400194 try:
kelvin8ec71442015-01-15 16:57:00 -0800195 self.handle.sendline( "" )
196 x = self.handle.expect( [
197 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500198
199 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800200 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500201 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400202
kelvin8ec71442015-01-15 16:57:00 -0800203 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800204 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800205 i = self.handle.expect( [
206 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800207 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400208
209 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800210 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800211 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800212 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800213 "config:property-set -p org.apache.karaf.shell\
214 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800215 karafTimeout )
216 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800218 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400219 return main.TRUE
220 else:
kelvin8ec71442015-01-15 16:57:00 -0800221 # If failed, send ctrl+c to process and try again
222 main.log.info( "Starting CLI failed. Retrying..." )
223 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800225 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
226 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400227 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800229 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800230 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800231 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 "config:property-set -p org.apache.karaf.shell\
233 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800234 karafTimeout )
235 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800236 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800237 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400238 return main.TRUE
239 else:
kelvin8ec71442015-01-15 16:57:00 -0800240 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400242 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": EOF exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400250 main.cleanup()
251 main.exit()
252 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800253 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400254 main.cleanup()
255 main.exit()
256
kelvin-onlab338f5512015-02-06 10:53:16 -0800257 def log( self, cmdStr , level = "" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800258 """
259 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800260 returns main.TRUE on success
261 returns main.FALSE if Error occured
262 Available level: DEBUG, TRACE, INFO, WARN, ERROR
263 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800264 """
265 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800266 lvlStr = ""
267 if level:
268 lvlStr = "--level=" + level
269
kelvin-onlab9f541032015-02-04 16:19:53 -0800270 self.handle.sendline( "" )
271 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800272 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800273 self.handle.expect( "onos>" )
274
275 response = self.handle.before
276 if re.search( "Error", response ):
277 return main.FALSE
278 return main.TRUE
279
280 except pexpect.EOF:
281 main.log.error( self.name + ": EOF exception found" )
282 main.log.error( self.name + ": " + self.handle.before )
283 main.cleanup()
284 main.exit()
285 except:
286 main.log.info( self.name + " ::::::" )
287 main.log.error( traceback.print_exc() )
288 main.log.info( self.name + " ::::::" )
289 main.cleanup()
290 main.exit()
291
kelvin-onlabd3b64892015-01-20 13:26:24 -0800292 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800293 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800294 Send a completely user specified string to
295 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400296 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800297
andrewonlaba18f6bf2014-10-13 19:31:54 -0400298 Warning: There are no sanity checking to commands
299 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800300 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400301 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800302
303 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
304 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800305 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800306 self.handle.expect( "onos>" )
Jon Hallaea67aa2015-01-23 13:30:57 -0800307 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
308 + self.name + "." )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400309
310 handle = self.handle.before
Jon Hall7bdfc122015-01-23 11:45:32 -0800311 # Remove control strings from output
312 ansiEscape = re.compile( r'\x1b[^m]*m' )
313 handle = ansiEscape.sub( '', handle )
Jon Hall44225f82015-01-23 13:45:14 -0800314 #Remove extra return chars that get added
Jon Hallaea67aa2015-01-23 13:30:57 -0800315 handle = re.sub( r"\s\r", "", handle )
316 handle = handle.strip()
Jon Hall7bdfc122015-01-23 11:45:32 -0800317 # parse for just the output, remove the cmd from handle
318 output = handle.split( cmdStr, 1 )[1]
kelvin8ec71442015-01-15 16:57:00 -0800319
andrewonlaba18f6bf2014-10-13 19:31:54 -0400320
Jon Hall7bdfc122015-01-23 11:45:32 -0800321 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800322 except TypeError:
323 main.log.exception( self.name + ": Object not as expected" )
324 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400325 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800326 main.log.error( self.name + ": EOF exception found" )
327 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400328 main.cleanup()
329 main.exit()
330 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800331 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400332 main.cleanup()
333 main.exit()
334
kelvin8ec71442015-01-15 16:57:00 -0800335 # IMPORTANT NOTE:
336 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800337 # the cli command changing 'a:b' with 'aB'.
338 # Ex ) onos:topology > onosTopology
339 # onos:links > onosLinks
340 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800341
kelvin-onlabd3b64892015-01-20 13:26:24 -0800342 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800343 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400344 Adds a new cluster node by ID and address information.
345 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800346 * nodeId
347 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400348 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800349 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800350 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400351 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800352 cmdStr = "add-node " + str( nodeId ) + " " +\
353 str( ONOSIp ) + " " + str( tcpPort )
354 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800355 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800356 main.log.error( "Error in adding node" )
357 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800358 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400359 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800360 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400361 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800362 except TypeError:
363 main.log.exception( self.name + ": Object not as expected" )
364 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400365 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800366 main.log.error( self.name + ": EOF exception found" )
367 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400368 main.cleanup()
369 main.exit()
370 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800371 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400372 main.cleanup()
373 main.exit()
374
kelvin-onlabd3b64892015-01-20 13:26:24 -0800375 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800376 """
andrewonlab86dc3082014-10-13 18:18:38 -0400377 Removes a cluster by ID
378 Issues command: 'remove-node [<node-id>]'
379 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800380 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800381 """
andrewonlab86dc3082014-10-13 18:18:38 -0400382 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400383
kelvin-onlabd3b64892015-01-20 13:26:24 -0800384 cmdStr = "remove-node " + str( nodeId )
385 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800386 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400387
388 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800389
Jon Halld4d4b372015-01-28 16:02:41 -0800390 except TypeError:
391 main.log.exception( self.name + ": Object not as expected" )
392 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800394 main.log.error( self.name + ": EOF exception found" )
395 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400396 main.cleanup()
397 main.exit()
398 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800399 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400400 main.cleanup()
401 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400402
kelvin8ec71442015-01-15 16:57:00 -0800403 def nodes( self ):
404 """
andrewonlab7c211572014-10-15 16:45:20 -0400405 List the nodes currently visible
406 Issues command: 'nodes'
407 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800408 """
andrewonlab7c211572014-10-15 16:45:20 -0400409 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800410 cmdStr = "nodes"
411 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400412 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800413 except TypeError:
414 main.log.exception( self.name + ": Object not as expected" )
415 return None
andrewonlab7c211572014-10-15 16:45:20 -0400416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800417 main.log.error( self.name + ": EOF exception found" )
418 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400419 main.cleanup()
420 main.exit()
421 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800422 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400423 main.cleanup()
424 main.exit()
425
kelvin8ec71442015-01-15 16:57:00 -0800426 def topology( self ):
427 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400428 Shows the current state of the topology
429 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800430 """
andrewonlab95ce8322014-10-13 14:12:04 -0400431 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800432 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800433 cmdStr = "onos:topology"
434 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800435 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400436 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800437 except TypeError:
438 main.log.exception( self.name + ": Object not as expected" )
439 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400443 main.cleanup()
444 main.exit()
445 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800446 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400447 main.cleanup()
448 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800449
kelvin-onlabd3b64892015-01-20 13:26:24 -0800450 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800451 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800452 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400453 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800454 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400455 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800456 cmdStr = "feature:install " + str( featureStr )
457 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800458 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400459 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800460 except TypeError:
461 main.log.exception( self.name + ": Object not as expected" )
462 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800464 main.log.error( self.name + ": EOF exception found" )
465 main.log.error( self.name + ": " + self.handle.before )
466 main.log.report( "Failed to install feature" )
467 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400468 main.cleanup()
469 main.exit()
470 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800471 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800472 main.log.report( "Failed to install feature" )
473 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400474 main.cleanup()
475 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800476
kelvin-onlabd3b64892015-01-20 13:26:24 -0800477 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800478 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479 Uninstalls a specified feature
480 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800481 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400482 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800483 cmdStr = "feature:uninstall " + str( featureStr )
484 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800485 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400486 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800487 except TypeError:
488 main.log.exception( self.name + ": Object not as expected" )
489 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400490 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800491 main.log.error( self.name + ": EOF exception found" )
492 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400493 main.cleanup()
494 main.exit()
495 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800496 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400497 main.cleanup()
498 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800499
kelvin-onlabd3b64892015-01-20 13:26:24 -0800500 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800501 """
Jon Hall7b02d952014-10-17 20:14:54 -0400502 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400503 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800504 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800505 """
andrewonlab86dc3082014-10-13 18:18:38 -0400506 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800507 if jsonFormat:
508 cmdStr = "devices -j"
509 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800510 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800511 handle variable here contains some ANSI escape color code
512 sequences at the end which are invisible in the print command
513 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800514 function. The repr( handle ) output when printed shows the
515 ANSI escape sequences. In json.loads( somestring ), this
516 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800517 json.loads would fail with the escape sequence. So we take off
518 that escape sequence using:
519
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
521 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800522 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800523 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
524 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400525 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400526 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800527 cmdStr = "devices"
528 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400529 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800530 except TypeError:
531 main.log.exception( self.name + ": Object not as expected" )
532 return None
andrewonlab7c211572014-10-15 16:45:20 -0400533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800534 main.log.error( self.name + ": EOF exception found" )
535 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400536 main.cleanup()
537 main.exit()
538 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800539 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400540 main.cleanup()
541 main.exit()
542
kelvin-onlabd3b64892015-01-20 13:26:24 -0800543 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800544 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800545 This balances the devices across all controllers
546 by issuing command: 'onos> onos:balance-masters'
547 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800548 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800549 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800550 cmdStr = "onos:balance-masters"
551 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800552 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800553 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800554 except TypeError:
555 main.log.exception( self.name + ": Object not as expected" )
556 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800557 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800558 main.log.error( self.name + ": EOF exception found" )
559 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800560 main.cleanup()
561 main.exit()
562 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800563 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800564 main.cleanup()
565 main.exit()
566
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800568 """
Jon Halle8217482014-10-17 13:49:14 -0400569 Lists all core links
570 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800572 """
Jon Halle8217482014-10-17 13:49:14 -0400573 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 if jsonFormat:
575 cmdStr = "links -j"
576 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800577 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800578 handle variable here contains some ANSI escape color code
579 sequences at the end which are invisible in the print command
580 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800581 function. The repr( handle ) output when printed shows the ANSI
582 escape sequences. In json.loads( somestring ), this somestring
583 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800584 fail with the escape sequence. So we take off that escape
585 sequence using:
586
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
588 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800589 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800590 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
591 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400592 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400593 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 cmdStr = "links"
595 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400596 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800597 except TypeError:
598 main.log.exception( self.name + ": Object not as expected" )
599 return None
Jon Halle8217482014-10-17 13:49:14 -0400600 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800601 main.log.error( self.name + ": EOF exception found" )
602 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400603 main.cleanup()
604 main.exit()
605 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800606 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400607 main.cleanup()
608 main.exit()
609
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800611 """
Jon Halle8217482014-10-17 13:49:14 -0400612 Lists all ports
613 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800615 """
Jon Halle8217482014-10-17 13:49:14 -0400616 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 if jsonFormat:
618 cmdStr = "ports -j"
619 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800620 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800621 handle variable here contains some ANSI escape color code
622 sequences at the end which are invisible in the print command
623 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800624 function. The repr( handle ) output when printed shows the ANSI
625 escape sequences. In json.loads( somestring ), this somestring
626 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800627 fail with the escape sequence. So we take off that escape
628 sequence using the following commads:
629
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
631 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800632 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
634 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400635 return handle1
636
Jon Halle8217482014-10-17 13:49:14 -0400637 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 cmdStr = "ports"
639 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800640 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800641 except TypeError:
642 main.log.exception( self.name + ": Object not as expected" )
643 return None
Jon Halle8217482014-10-17 13:49:14 -0400644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800645 main.log.error( self.name + ": EOF exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400647 main.cleanup()
648 main.exit()
649 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800650 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400651 main.cleanup()
652 main.exit()
653
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800655 """
Jon Hall983a1702014-10-28 18:44:22 -0400656 Lists all devices and the controllers with roles assigned to them
657 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800659 """
andrewonlab7c211572014-10-15 16:45:20 -0400660 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 if jsonFormat:
662 cmdStr = "roles -j"
663 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800664 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800665 handle variable here contains some ANSI escape color code
666 sequences at the end which are invisible in the print command
667 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800668 function. The repr( handle ) output when printed shows the ANSI
669 escape sequences. In json.loads( somestring ), this somestring
670 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800671 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500672
Jon Halle3f39ff2015-01-13 11:50:53 -0800673 So we take off that escape sequence using the following
674 commads:
675
kelvin-onlabd3b64892015-01-20 13:26:24 -0800676 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
677 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800678 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800679 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
680 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400681 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400682
andrewonlab7c211572014-10-15 16:45:20 -0400683 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 cmdStr = "roles"
685 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800686 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800687 except TypeError:
688 main.log.exception( self.name + ": Object not as expected" )
689 return None
Jon Hall983a1702014-10-28 18:44:22 -0400690 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800691 main.log.error( self.name + ": EOF exception found" )
692 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400693 main.cleanup()
694 main.exit()
695 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800696 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400697 main.cleanup()
698 main.exit()
699
kelvin-onlabd3b64892015-01-20 13:26:24 -0800700 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800701 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800702 Given the a string containing the json representation of the "roles"
703 cli command and a partial or whole device id, returns a json object
704 containing the roles output for the first device whose id contains
705 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400706
707 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800708 A dict of the role assignments for the given device or
709 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800710 """
Jon Hall983a1702014-10-28 18:44:22 -0400711 try:
712 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800713 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400714 return None
715 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 rawRoles = self.roles()
717 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800718 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800719 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800720 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400722 return device
723 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800724 except TypeError:
725 main.log.exception( self.name + ": Object not as expected" )
726 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400727 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800728 main.log.error( self.name + ": EOF exception found" )
729 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400730 main.cleanup()
731 main.exit()
732 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800733 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400734 main.cleanup()
735 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800736
kelvin-onlabd3b64892015-01-20 13:26:24 -0800737 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800738 """
Jon Hall94fd0472014-12-08 11:52:42 -0800739 Iterates through each device and checks if there is a master assigned
740 Returns: main.TRUE if each device has a master
741 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800742 """
Jon Hall94fd0472014-12-08 11:52:42 -0800743 try:
744 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 rawRoles = self.roles()
746 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800747 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800748 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800749 # print device
750 if device[ 'master' ] == "none":
751 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800752 return main.FALSE
753 return main.TRUE
754
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800761 main.cleanup()
762 main.exit()
763 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800765 main.cleanup()
766 main.exit()
767
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800769 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400770 Returns string of paths, and the cost.
771 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800772 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
775 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800776 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800777 main.log.error( "Error in getting paths" )
778 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400779 else:
kelvin8ec71442015-01-15 16:57:00 -0800780 path = handle.split( ";" )[ 0 ]
781 cost = handle.split( ";" )[ 1 ]
782 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800783 except TypeError:
784 main.log.exception( self.name + ": Object not as expected" )
785 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400786 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800787 main.log.error( self.name + ": EOF exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400789 main.cleanup()
790 main.exit()
791 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800792 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400793 main.cleanup()
794 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800795
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
Jon Hallffb386d2014-11-21 13:43:38 -0800798 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400799 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800801 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400802 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 if jsonFormat:
804 cmdStr = "hosts -j"
805 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800806 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800807 handle variable here contains some ANSI escape color code
808 sequences at the end which are invisible in the print command
809 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800810 function. The repr( handle ) output when printed shows the ANSI
811 escape sequences. In json.loads( somestring ), this somestring
812 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800813 fail with the escape sequence. So we take off that escape
814 sequence using:
815
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
817 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800818 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
820 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400821 return handle1
822 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 cmdStr = "hosts"
824 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400825 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800826 except TypeError:
827 main.log.exception( self.name + ": Object not as expected" )
828 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400829 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800830 main.log.error( self.name + ": EOF exception found" )
831 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400832 main.cleanup()
833 main.exit()
834 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800835 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400836 main.cleanup()
837 main.exit()
838
kelvin-onlabd3b64892015-01-20 13:26:24 -0800839 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800840 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400841 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800842
843 Note: mac must be a colon seperated mac address, but could be a
844 partial mac address
845
Jon Hall42db6dc2014-10-24 19:03:48 -0400846 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400848 import json
849 try:
kelvin8ec71442015-01-15 16:57:00 -0800850 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400851 return None
852 else:
853 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800854 rawHosts = self.hosts()
855 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800856 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800858 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800859 if not host:
860 pass
861 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400862 return host
863 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800864 except TypeError:
865 main.log.exception( self.name + ": Object not as expected" )
866 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800868 main.log.error( self.name + ": EOF exception found" )
869 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400870 main.cleanup()
871 main.exit()
872 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800873 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400874 main.cleanup()
875 main.exit()
876
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800878 """
879 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400880 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800881
andrewonlab3f0a4af2014-10-17 12:25:14 -0400882 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400884 IMPORTANT:
885 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800886 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400887 Furthermore, it assumes that value of VLAN is '-1'
888 Description:
kelvin8ec71442015-01-15 16:57:00 -0800889 Converts mininet hosts ( h1, h2, h3... ) into
890 ONOS format ( 00:00:00:00:00:01/-1 , ... )
891 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400892 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400894
kelvin-onlabd3b64892015-01-20 13:26:24 -0800895 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800896 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 hostHex = hex( int( host ) ).zfill( 12 )
898 hostHex = str( hostHex ).replace( 'x', '0' )
899 i = iter( str( hostHex ) )
900 hostHex = ":".join( a + b for a, b in zip( i, i ) )
901 hostHex = hostHex + "/-1"
902 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400903
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400905
Jon Halld4d4b372015-01-28 16:02:41 -0800906 except TypeError:
907 main.log.exception( self.name + ": Object not as expected" )
908 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400909 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800910 main.log.error( self.name + ": EOF exception found" )
911 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400912 main.cleanup()
913 main.exit()
914 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800915 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400916 main.cleanup()
917 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400918
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800920 """
andrewonlabe6745342014-10-17 14:29:13 -0400921 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800922 * hostIdOne: ONOS host id for host1
923 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400924 Description:
kelvin8ec71442015-01-15 16:57:00 -0800925 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500926 specifying the two hosts.
kelvin8ec71442015-01-15 16:57:00 -0800927 """
andrewonlabe6745342014-10-17 14:29:13 -0400928 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 cmdStr = "add-host-intent " + str( hostIdOne ) +\
930 " " + str( hostIdTwo )
931 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800932 if re.search( "Error", handle ):
933 main.log.error( "Error in adding Host intent" )
934 return handle
935 else:
936 main.log.info( "Host intent installed between " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800937 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800938 return main.TRUE
939
Jon Halld4d4b372015-01-28 16:02:41 -0800940 except TypeError:
941 main.log.exception( self.name + ": Object not as expected" )
942 return None
Hari Krishnaccfb0d52015-02-19 09:38:29 -0800943
andrewonlabe6745342014-10-17 14:29:13 -0400944 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400947 main.cleanup()
948 main.exit()
949 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400951 main.cleanup()
952 main.exit()
953
kelvin-onlabd3b64892015-01-20 13:26:24 -0800954 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800955 """
andrewonlab7b31d232014-10-24 13:31:47 -0400956 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 * ingressDevice: device id of ingress device
958 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400959 Optional:
960 TODO: Still needs to be implemented via dev side
kelvin-onlab898a6c62015-01-16 14:13:53 -0800961 """
andrewonlab7b31d232014-10-24 13:31:47 -0400962 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
964 " " + str( egressDevice )
965 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800966 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800967 if re.search( "Error", handle ):
andrewonlab7b31d232014-10-24 13:31:47 -0400968 return handle
969 else:
970 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800971 except TypeError:
972 main.log.exception( self.name + ": Object not as expected" )
973 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400974 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800975 main.log.error( self.name + ": EOF exception found" )
976 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400977 main.cleanup()
978 main.exit()
979 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800980 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400981 main.cleanup()
982 main.exit()
983
kelvin-onlabd3b64892015-01-20 13:26:24 -0800984 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -0800985 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 ingressDevice,
987 egressDevice,
988 portIngress="",
989 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800990 ethType="",
991 ethSrc="",
992 ethDst="",
993 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800995 ipProto="",
996 ipSrc="",
997 ipDst="",
998 tcpSrc="",
999 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001000 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001001 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001002 * ingressDevice: device id of ingress device
1003 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001004 Optional:
1005 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001006 * ethSrc: specify ethSrc ( i.e. src mac addr )
1007 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001008 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001010 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001011 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001012 * ipSrc: specify ip source address
1013 * ipDst: specify ip destination address
1014 * tcpSrc: specify tcp source port
1015 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001016 Description:
kelvin8ec71442015-01-15 16:57:00 -08001017 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001018 specifying device id's and optional fields
1019
Jon Halle3f39ff2015-01-13 11:50:53 -08001020 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001021 options developers provide for point-to-point
1022 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001023 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001024 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001025 cmd = ""
1026
kelvin8ec71442015-01-15 16:57:00 -08001027 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001028 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001030 and not ipProto and not ipSrc and not ipDst \
1031 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001032 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001033
andrewonlab289e4b72014-10-21 21:24:18 -04001034 else:
andrewonlab36af3822014-11-18 17:48:18 -05001035 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001036
andrewonlab0c0a6772014-10-22 12:31:18 -04001037 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001038 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001039 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001040 cmd += " --ethSrc " + str( ethSrc )
1041 if ethDst:
1042 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001043 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001044 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001046 cmd += " --lambda "
1047 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001048 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001049 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001050 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001051 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001052 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001053 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001054 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001055 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001056 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001057
kelvin8ec71442015-01-15 16:57:00 -08001058 # Check whether the user appended the port
1059 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 if "/" in ingressDevice:
1061 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001062 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 if not portIngress:
kelvin8ec71442015-01-15 16:57:00 -08001064 main.log.error( "You must specify " +
1065 "the ingress port" )
1066 # TODO: perhaps more meaningful return
andrewonlab36af3822014-11-18 17:48:18 -05001067 return main.FALSE
1068
kelvin8ec71442015-01-15 16:57:00 -08001069 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001070 str( ingressDevice ) + "/" +\
1071 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 if "/" in egressDevice:
1074 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001075 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001077 main.log.error( "You must specify " +
1078 "the egress port" )
andrewonlab36af3822014-11-18 17:48:18 -05001079 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001080
kelvin8ec71442015-01-15 16:57:00 -08001081 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 str( egressDevice ) + "/" +\
1083 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001084
kelvin-onlab898a6c62015-01-16 14:13:53 -08001085 handle = self.sendline( cmd )
1086 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001087 main.log.error( "Error in adding point-to-point intent" )
Jon Hall47a93fb2015-01-06 16:46:06 -08001088 return main.FALSE
andrewonlab4dbb4d82014-10-17 18:22:31 -04001089 else:
1090 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001091 except TypeError:
1092 main.log.exception( self.name + ": Object not as expected" )
1093 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001094 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001095 main.log.error( self.name + ": EOF exception found" )
1096 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001097 main.cleanup()
1098 main.exit()
1099 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001100 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001101 main.cleanup()
1102 main.exit()
1103
kelvin-onlabd3b64892015-01-20 13:26:24 -08001104 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001105 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 ingressDevice1,
1107 ingressDevice2,
1108 egressDevice,
1109 portIngress="",
1110 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001111 ethType="",
1112 ethSrc="",
1113 ethDst="",
1114 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001116 ipProto="",
1117 ipSrc="",
1118 ipDst="",
1119 tcpSrc="",
1120 tcpDst="",
1121 setEthSrc="",
1122 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001123 """
shahshreyad0c80432014-12-04 16:56:05 -08001124 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001125 This function assumes that there would be 2 ingress devices and
1126 one egress device. For more number of ingress devices, this
1127 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001128 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 * ingressDevice1: device id of ingress device1
1130 * ingressDevice2: device id of ingress device2
1131 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001132 Optional:
1133 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001134 * ethSrc: specify ethSrc ( i.e. src mac addr )
1135 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001136 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001138 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001139 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001140 * ipSrc: specify ip source address
1141 * ipDst: specify ip destination address
1142 * tcpSrc: specify tcp source port
1143 * tcpDst: specify tcp destination port
1144 * setEthSrc: action to Rewrite Source MAC Address
1145 * setEthDst: action to Rewrite Destination MAC Address
1146 Description:
kelvin8ec71442015-01-15 16:57:00 -08001147 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001148 specifying device id's and optional fields
1149
Jon Halle3f39ff2015-01-13 11:50:53 -08001150 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001151 options developers provide for multipointpoint-to-singlepoint
1152 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001153 """
shahshreyad0c80432014-12-04 16:56:05 -08001154 try:
1155 cmd = ""
1156
kelvin8ec71442015-01-15 16:57:00 -08001157 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001158 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001160 and not ipProto and not ipSrc and not ipDst\
1161 and not tcpSrc and not tcpDst and not setEthSrc\
1162 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001163 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001164
1165 else:
1166 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001167
shahshreyad0c80432014-12-04 16:56:05 -08001168 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001169 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001170 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001171 cmd += " --ethSrc " + str( ethSrc )
1172 if ethDst:
1173 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001174 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001175 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001177 cmd += " --lambda "
1178 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001179 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001180 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001181 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001182 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001184 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001186 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001187 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001188 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001190 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001191 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001192
kelvin8ec71442015-01-15 16:57:00 -08001193 # Check whether the user appended the port
1194 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 if "/" in ingressDevice1:
1196 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001197 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001199 main.log.error( "You must specify " +
1200 "the ingress port1" )
1201 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001202 return main.FALSE
1203
kelvin8ec71442015-01-15 16:57:00 -08001204 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 str( ingressDevice1 ) + "/" +\
1206 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001207
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if "/" in ingressDevice2:
1209 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001210 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001212 main.log.error( "You must specify " +
1213 "the ingress port2" )
1214 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001215 return main.FALSE
1216
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 str( ingressDevice2 ) + "/" +\
1219 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001220
kelvin-onlabd3b64892015-01-20 13:26:24 -08001221 if "/" in egressDevice:
1222 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001223 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001225 main.log.error( "You must specify " +
1226 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001227 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001228
kelvin8ec71442015-01-15 16:57:00 -08001229 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 str( egressDevice ) + "/" +\
1231 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001232 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001233 handle = self.sendline( cmd )
1234 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001235 main.log.error( "Error in adding point-to-point intent" )
shahshreyad0c80432014-12-04 16:56:05 -08001236 return self.handle
1237 else:
1238 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001239 except TypeError:
1240 main.log.exception( self.name + ": Object not as expected" )
1241 return None
shahshreyad0c80432014-12-04 16:56:05 -08001242 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001243 main.log.error( self.name + ": EOF exception found" )
1244 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001245 main.cleanup()
1246 main.exit()
1247 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001248 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001249 main.cleanup()
1250 main.exit()
1251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 def removeIntent( self, intentId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001254 Remove intent for specified intent id
Jon Halle3f39ff2015-01-13 11:50:53 -08001255
1256 Returns:
1257 main.False on error and
1258 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001260 try:
shahshreyac033d022015-02-20 16:10:19 -08001261 cmdStr = "remove-intent org.onosproject.cli " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001263 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001265 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001266 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001267 # TODO: Should this be main.TRUE
1268 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001269 except TypeError:
1270 main.log.exception( self.name + ": Object not as expected" )
1271 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001272 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001273 main.log.error( self.name + ": EOF exception found" )
1274 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001275 main.cleanup()
1276 main.exit()
1277 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001278 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001279 main.cleanup()
1280 main.exit()
1281
kelvin-onlabd3b64892015-01-20 13:26:24 -08001282 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001283 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001284 NOTE: This method should be used after installing application:
1285 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001286 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001288 Description:
1289 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001290 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001291 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001292 if jsonFormat:
1293 cmdStr = "routes -j"
1294 handleTmp = self.sendline( cmdStr )
1295 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1296 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001297 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001298 cmdStr = "routes"
1299 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001300 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001301 except TypeError:
1302 main.log.exception( self.name + ": Object not as expected" )
1303 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001305 main.log.error( self.name + ": EOF exception found" )
1306 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001307 main.cleanup()
1308 main.exit()
1309 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001310 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001311 main.cleanup()
1312 main.exit()
1313
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlab377693f2014-10-21 16:00:30 -04001316 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001318 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001319 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001320 """
andrewonlabe6745342014-10-17 14:29:13 -04001321 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 if jsonFormat:
1323 cmdStr = "intents -j"
1324 handle = self.sendline( cmdStr )
1325 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1326 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001327 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001328 cmdStr = "intents"
1329 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001330 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001331 except TypeError:
1332 main.log.exception( self.name + ": Object not as expected" )
1333 return None
andrewonlabe6745342014-10-17 14:29:13 -04001334 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001335 main.log.error( self.name + ": EOF exception found" )
1336 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001337 main.cleanup()
1338 main.exit()
1339 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001340 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001341 main.cleanup()
1342 main.exit()
1343
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001345 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001346 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001348 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001349 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001350 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001351 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 if jsonFormat:
1353 cmdStr = "flows -j"
1354 handle = self.sendline( cmdStr )
1355 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1356 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001357 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 cmdStr = "flows"
1359 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001360 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001361 main.log.error( self.name + ".flows() response: " +
1362 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001363 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001364 except TypeError:
1365 main.log.exception( self.name + ": Object not as expected" )
1366 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001367 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001368 main.log.error( self.name + ": EOF exception found" )
1369 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001370 main.cleanup()
1371 main.exit()
1372 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001373 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001374 main.cleanup()
1375 main.exit()
1376
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1378 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001379 """
andrewonlab87852b02014-11-19 18:44:19 -05001380 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001381 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001382 a specific point-to-point intent definition
1383 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 * dpidSrc: specify source dpid
1385 * dpidDst: specify destination dpid
1386 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001387 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001389 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001391 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001392 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001393 """
andrewonlab87852b02014-11-19 18:44:19 -05001394 try:
kelvin8ec71442015-01-15 16:57:00 -08001395 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1397 str( numIntents )
1398 if numMult:
1399 cmd += " " + str( numMult )
1400 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001401 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 if appId:
1403 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1406 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001407 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001409 main.log.info( handle )
1410 # Split result by newline
1411 newline = handle.split( "\r\r\n" )
1412 # Ignore the first object of list, which is empty
1413 newline = newline[ 1: ]
1414 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001415 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001416 result = result.split( ": " )
1417 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1419 main.log.info( latResult )
1420 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001421 else:
1422 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001423 except TypeError:
1424 main.log.exception( self.name + ": Object not as expected" )
1425 return None
andrewonlab87852b02014-11-19 18:44:19 -05001426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001427 main.log.error( self.name + ": EOF exception found" )
1428 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001429 main.cleanup()
1430 main.exit()
1431 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001432 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001433 main.cleanup()
1434 main.exit()
1435
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001437 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001438 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001439 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001440 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001441 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001442 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 if jsonFormat:
1444 cmdStr = "intents-events-metrics -j"
1445 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1448 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001449 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 cmdStr = "intents-events-metrics"
1451 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001452 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001453 except TypeError:
1454 main.log.exception( self.name + ": Object not as expected" )
1455 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001456 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001457 main.log.error( self.name + ": EOF exception found" )
1458 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001459 main.cleanup()
1460 main.exit()
1461 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001462 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001463 main.cleanup()
1464 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001465
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001467 """
1468 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001469 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001470 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001471 """
andrewonlab867212a2014-10-22 20:13:38 -04001472 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 if jsonFormat:
1474 cmdStr = "topology-events-metrics -j"
1475 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001476 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001477 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1478 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001479 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 cmdStr = "topology-events-metrics"
1481 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001482 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001483 except TypeError:
1484 main.log.exception( self.name + ": Object not as expected" )
1485 return None
andrewonlab867212a2014-10-22 20:13:38 -04001486 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001487 main.log.error( self.name + ": EOF exception found" )
1488 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001489 main.cleanup()
1490 main.exit()
1491 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001492 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001493 main.cleanup()
1494 main.exit()
1495
kelvin8ec71442015-01-15 16:57:00 -08001496 # Wrapper functions ****************
1497 # Wrapper functions use existing driver
1498 # functions and extends their use case.
1499 # For example, we may use the output of
1500 # a normal driver function, and parse it
1501 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001502
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001504 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001505 Description:
1506 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001507 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001508 try:
kelvin8ec71442015-01-15 16:57:00 -08001509 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 intentsStr = self.intents()
1511 allIntentList = []
1512 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001513
kelvin8ec71442015-01-15 16:57:00 -08001514 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1516 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001517 if "onos>" in intents:
1518 continue
1519 elif "intents" in intents:
1520 continue
1521 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 lineList = intents.split( " " )
1523 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001524
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001526
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001528 if not intents:
1529 continue
1530 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001532
kelvin-onlabd3b64892015-01-20 13:26:24 -08001533 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001534
Jon Halld4d4b372015-01-28 16:02:41 -08001535 except TypeError:
1536 main.log.exception( self.name + ": Object not as expected" )
1537 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001539 main.log.error( self.name + ": EOF exception found" )
1540 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001541 main.cleanup()
1542 main.exit()
1543 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001544 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001545 main.cleanup()
1546 main.exit()
1547
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001549 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001550 Use 'devices' function to obtain list of all devices
1551 and parse the result to obtain a list of all device
1552 id's. Returns this list. Returns empty list if no
1553 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001554 List is ordered sequentially
1555
andrewonlab3e15ead2014-10-15 14:21:34 -04001556 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001557 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001558 the ids. By obtaining the list of device ids on the fly,
1559 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001560 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001561 try:
kelvin8ec71442015-01-15 16:57:00 -08001562 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 devicesStr = self.devices( jsonFormat=False )
1564 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001565
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001567 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 return idList
kelvin8ec71442015-01-15 16:57:00 -08001569
1570 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001572 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001574 # Split list further into arguments before and after string
1575 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 # append to idList
1577 for arg in tempList:
1578 idList.append( arg.split( "id=" )[ 1 ] )
1579 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001580
Jon Halld4d4b372015-01-28 16:02:41 -08001581 except TypeError:
1582 main.log.exception( self.name + ": Object not as expected" )
1583 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001584 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001585 main.log.error( self.name + ": EOF exception found" )
1586 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001587 main.cleanup()
1588 main.exit()
1589 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001590 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001591 main.cleanup()
1592 main.exit()
1593
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001595 """
andrewonlab7c211572014-10-15 16:45:20 -04001596 Uses 'nodes' function to obtain list of all nodes
1597 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001598 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001599 Returns:
1600 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001601 """
andrewonlab7c211572014-10-15 16:45:20 -04001602 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 nodesStr = self.nodes()
1604 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001605
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001607 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001609
kelvin-onlabd3b64892015-01-20 13:26:24 -08001610 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001611 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001612
kelvin8ec71442015-01-15 16:57:00 -08001613 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 nodesList = nodesStr.split( "," )
1615 tempList = [ node for node in nodesList if "id=" in node ]
1616 for arg in tempList:
1617 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001618
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 return idList
kelvin8ec71442015-01-15 16:57:00 -08001620
Jon Halld4d4b372015-01-28 16:02:41 -08001621 except TypeError:
1622 main.log.exception( self.name + ": Object not as expected" )
1623 return None
andrewonlab7c211572014-10-15 16:45:20 -04001624 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001625 main.log.error( self.name + ": EOF exception found" )
1626 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001627 main.cleanup()
1628 main.exit()
1629 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001630 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001631 main.cleanup()
1632 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001633
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001635 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001636 Return the first device from the devices api whose 'id' contains 'dpid'
1637 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001638 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001639 import json
1640 try:
kelvin8ec71442015-01-15 16:57:00 -08001641 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001642 return None
1643 else:
kelvin8ec71442015-01-15 16:57:00 -08001644 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 rawDevices = self.devices()
1646 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001647 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001648 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001649 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1650 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001651 return device
1652 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001653 except TypeError:
1654 main.log.exception( self.name + ": Object not as expected" )
1655 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001656 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001657 main.log.error( self.name + ": EOF exception found" )
1658 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001659 main.cleanup()
1660 main.exit()
1661 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001662 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001663 main.cleanup()
1664 main.exit()
1665
kelvin-onlabd3b64892015-01-20 13:26:24 -08001666 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001667 """
1668 Checks the number of swithes & links that ONOS sees against the
1669 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001670 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001671
Jon Hall42db6dc2014-10-24 19:03:48 -04001672 Params: ip = ip used for the onos cli
1673 numoswitch = expected number of switches
1674 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001675 logLevel = level to log to. Currently accepts
1676 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001677
1678
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001680
kelvin8ec71442015-01-15 16:57:00 -08001681 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001682 main.FALSE if the numer of switches and links is incorrect,
1683 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001684 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001685 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001686 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001687 if topology == {}:
1688 return main.ERROR
1689 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001690 # Is the number of switches is what we expected
1691 devices = topology.get( 'devices', False )
1692 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001693 if devices == False or links == False:
1694 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001696 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001697 linkCheck = ( int( links ) == int( numolink ) )
1698 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001699 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001700 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001701 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001702 result = main.TRUE
1703 else:
1704 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 "The number of links and switches does not matc\
1706 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001707 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001708 output = output + "\n ONOS sees %i devices (%i expected) \
1709 and %i links (%i expected)" % (
1710 int( devices ), int( numoswitch ), int( links ),
1711 int( numolink ) )
1712 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001713 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001714 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001715 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001716 else:
kelvin8ec71442015-01-15 16:57:00 -08001717 main.log.info( output )
1718 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001719 except TypeError:
1720 main.log.exception( self.name + ": Object not as expected" )
1721 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001723 main.log.error( self.name + ": EOF exception found" )
1724 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001725 main.cleanup()
1726 main.exit()
1727 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001728 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001729 main.cleanup()
1730 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001731
kelvin-onlabd3b64892015-01-20 13:26:24 -08001732 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001733 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001734 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001735 deviceId must be the id of a device as seen in the onos devices command
1736 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001737 role must be either master, standby, or none
1738
Jon Halle3f39ff2015-01-13 11:50:53 -08001739 Returns:
1740 main.TRUE or main.FALSE based on argument verification and
1741 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001742 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001743 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001744 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001745 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001746 cmdStr = "device-role " +\
1747 str( deviceId ) + " " +\
1748 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001749 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001751 if re.search( "Error", handle ):
1752 # end color output to escape any colours
1753 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001754 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001755 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001756 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001757 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001758 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001759 main.log.error( "Invalid 'role' given to device_role(). " +
1760 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001761 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001762 except TypeError:
1763 main.log.exception( self.name + ": Object not as expected" )
1764 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001766 main.log.error( self.name + ": EOF exception found" )
1767 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001768 main.cleanup()
1769 main.exit()
1770 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001771 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001772 main.cleanup()
1773 main.exit()
1774
kelvin-onlabd3b64892015-01-20 13:26:24 -08001775 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001776 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001777 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001778 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001779 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001780 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001781 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 if jsonFormat:
1783 cmdStr = "clusters -j"
1784 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001785 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001786 handle variable here contains some ANSI escape color code
1787 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001788 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001789 function. The repr( handle ) output when printed shows the ANSI
1790 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001791 variable is actually repr( somestring ) and json.loads would
1792 fail with the escape sequence. So we take off that escape
1793 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001794
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1796 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001797 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001798 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1799 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001800 return handle1
1801 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 cmdStr = "clusters"
1803 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001804 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001805 except TypeError:
1806 main.log.exception( self.name + ": Object not as expected" )
1807 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001811 main.cleanup()
1812 main.exit()
1813 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001814 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001815 main.cleanup()
1816 main.exit()
1817
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001819 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001820 CLI command to get the current leader for the Election test application
1821 NOTE: Requires installation of the onos-app-election feature
1822 Returns: Node IP of the leader if one exists
1823 None if none exists
1824 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001825 """
Jon Hall94fd0472014-12-08 11:52:42 -08001826 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001827 cmdStr = "election-test-leader"
1828 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001829 # Leader
1830 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001831 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 nodeSearch = re.search( leaderPattern, response )
1833 if nodeSearch:
1834 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001835 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001836 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001837 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001838 # no leader
1839 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001840 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 nullSearch = re.search( nullPattern, response )
1842 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001843 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001844 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001845 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001847 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 if re.search( errorPattern, response ):
1849 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001850 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001851 return main.FALSE
1852 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001853 main.log.error( "Error in election_test_leader: " +
1854 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001855 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001856 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001857 except TypeError:
1858 main.log.exception( self.name + ": Object not as expected" )
1859 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001860 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001861 main.log.error( self.name + ": EOF exception found" )
1862 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001863 main.cleanup()
1864 main.exit()
1865 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001866 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001867 main.cleanup()
1868 main.exit()
1869
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001871 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 CLI command to run for leadership of the Election test application.
1873 NOTE: Requires installation of the onos-app-election feature
1874 Returns: Main.TRUE on success
1875 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001876 """
Jon Hall94fd0472014-12-08 11:52:42 -08001877 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001878 cmdStr = "election-test-run"
1879 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001880 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001881 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001883 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001884 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001885 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001886 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001887 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001888 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001889 errorPattern = "Command\snot\sfound"
1890 if re.search( errorPattern, response ):
1891 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001892 return main.FALSE
1893 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001894 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001895 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001896 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001897 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001898 except TypeError:
1899 main.log.exception( self.name + ": Object not as expected" )
1900 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001901 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001902 main.log.error( self.name + ": EOF exception found" )
1903 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001904 main.cleanup()
1905 main.exit()
1906 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001907 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001908 main.cleanup()
1909 main.exit()
1910
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001912 """
Jon Hall94fd0472014-12-08 11:52:42 -08001913 * CLI command to withdraw the local node from leadership election for
1914 * the Election test application.
1915 #NOTE: Requires installation of the onos-app-election feature
1916 Returns: Main.TRUE on success
1917 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001918 """
Jon Hall94fd0472014-12-08 11:52:42 -08001919 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001920 cmdStr = "election-test-withdraw"
1921 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001922 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001923 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001924 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001925 if re.search( successPattern, response ):
1926 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001927 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001928 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001929 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001930 errorPattern = "Command\snot\sfound"
1931 if re.search( errorPattern, response ):
1932 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001933 return main.FALSE
1934 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001935 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001936 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001937 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001938 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001939 except TypeError:
1940 main.log.exception( self.name + ": Object not as expected" )
1941 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001942 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001943 main.log.error( self.name + ": EOF exception found" )
1944 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001945 main.cleanup()
1946 main.exit()
1947 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001948 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001949 main.cleanup()
1950 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001951
kelvin8ec71442015-01-15 16:57:00 -08001952 def getDevicePortsEnabledCount( self, dpid ):
1953 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001954 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001955 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001956 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001957 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1959 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001960 if re.search( "No such device", output ):
1961 main.log.error( "Error in getting ports" )
1962 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001963 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001964 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001965 except TypeError:
1966 main.log.exception( self.name + ": Object not as expected" )
1967 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001969 main.log.error( self.name + ": EOF exception found" )
1970 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001971 main.cleanup()
1972 main.exit()
1973 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001974 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001975 main.cleanup()
1976 main.exit()
1977
kelvin8ec71442015-01-15 16:57:00 -08001978 def getDeviceLinksActiveCount( self, dpid ):
1979 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001980 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001981 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001982 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001983 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
1985 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001986 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001987 main.log.error( "Error in getting ports " )
1988 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001989 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001990 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001991 except TypeError:
1992 main.log.exception( self.name + ": Object not as expected" )
1993 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001995 main.log.error( self.name + ": EOF exception found" )
1996 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001997 main.cleanup()
1998 main.exit()
1999 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002000 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002001 main.cleanup()
2002 main.exit()
2003
kelvin8ec71442015-01-15 16:57:00 -08002004 def getAllIntentIds( self ):
2005 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002006 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002007 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002008 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002009 cmdStr = "onos:intents | grep id="
2010 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002011 if re.search( "Error", output ):
2012 main.log.error( "Error in getting ports" )
2013 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002014 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002015 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002016 except TypeError:
2017 main.log.exception( self.name + ": Object not as expected" )
2018 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002020 main.log.error( self.name + ": EOF exception found" )
2021 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002022 main.cleanup()
2023 main.exit()
2024 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002025 main.log.exception( self.name + ": Uncaught exception!" )
2026 main.cleanup()
2027 main.exit()
2028
Jon Hall3f45d112015-02-24 16:42:56 -08002029 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002030 """
Jon Hall3f45d112015-02-24 16:42:56 -08002031 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002032 """
Jon Halld4d4b372015-01-28 16:02:41 -08002033 try:
Jon Hall3f45d112015-02-24 16:42:56 -08002034 intents = self.intents( )
2035 intentStates = []
2036 out = []
2037 for intent in json.loads( intents ):
2038 intentStates.append( intent.get( 'state', None ) )
2039 for i in set( intentStates ):
2040 out.append( (i, intentStates.count( i ) ) )
2041 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002042 except TypeError:
2043 main.log.exception( self.name + ": Object not as expected" )
2044 return None
2045 except pexpect.EOF:
2046 main.log.error( self.name + ": EOF exception found" )
2047 main.log.error( self.name + ": " + self.handle.before )
2048 main.cleanup()
2049 main.exit()
2050 except:
2051 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002052 main.cleanup()
2053 main.exit()