blob: d312f16f6b10b7a8bc8151361f4da5ed6b0a503c [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:
shahshreya74cca802015-02-26 12:24:01 -0800483 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
484 handle = self.sendline( cmdStr )
shahshreya280223a2015-02-26 12:25:25 -0800485 if handle != '':
shahshreya74cca802015-02-26 12:24:01 -0800486 cmdStr = "feature:uninstall " + str( featureStr )
487 self.sendline( cmdStr )
488 # TODO: Check for possible error responses from karaf
shahshreya280223a2015-02-26 12:25:25 -0800489 else:
490 main.log.info( "Feature needs to be installed before uninstalling it" )
491 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800492 except TypeError:
493 main.log.exception( self.name + ": Object not as expected" )
494 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400495 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800496 main.log.error( self.name + ": EOF exception found" )
497 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400498 main.cleanup()
499 main.exit()
500 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800501 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400502 main.cleanup()
503 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800504
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800506 """
Jon Hall7b02d952014-10-17 20:14:54 -0400507 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400508 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800510 """
andrewonlab86dc3082014-10-13 18:18:38 -0400511 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800512 if jsonFormat:
513 cmdStr = "devices -j"
514 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800515 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800516 handle variable here contains some ANSI escape color code
517 sequences at the end which are invisible in the print command
518 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800519 function. The repr( handle ) output when printed shows the
520 ANSI escape sequences. In json.loads( somestring ), this
521 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800522 json.loads would fail with the escape sequence. So we take off
523 that escape sequence using:
524
kelvin-onlabd3b64892015-01-20 13:26:24 -0800525 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
526 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800527 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800528 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
529 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400530 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400531 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800532 cmdStr = "devices"
533 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400534 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800535 except TypeError:
536 main.log.exception( self.name + ": Object not as expected" )
537 return None
andrewonlab7c211572014-10-15 16:45:20 -0400538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800539 main.log.error( self.name + ": EOF exception found" )
540 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400541 main.cleanup()
542 main.exit()
543 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800544 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400545 main.cleanup()
546 main.exit()
547
kelvin-onlabd3b64892015-01-20 13:26:24 -0800548 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800549 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800550 This balances the devices across all controllers
551 by issuing command: 'onos> onos:balance-masters'
552 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800553 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800554 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 cmdStr = "onos:balance-masters"
556 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800557 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800558 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800559 except TypeError:
560 main.log.exception( self.name + ": Object not as expected" )
561 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800562 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800563 main.log.error( self.name + ": EOF exception found" )
564 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800565 main.cleanup()
566 main.exit()
567 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800568 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800569 main.cleanup()
570 main.exit()
571
kelvin-onlabd3b64892015-01-20 13:26:24 -0800572 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800573 """
Jon Halle8217482014-10-17 13:49:14 -0400574 Lists all core links
575 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800577 """
Jon Halle8217482014-10-17 13:49:14 -0400578 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800579 if jsonFormat:
580 cmdStr = "links -j"
581 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800582 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800583 handle variable here contains some ANSI escape color code
584 sequences at the end which are invisible in the print command
585 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800586 function. The repr( handle ) output when printed shows the ANSI
587 escape sequences. In json.loads( somestring ), this somestring
588 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800589 fail with the escape sequence. So we take off that escape
590 sequence using:
591
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
593 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800594 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800595 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
596 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400597 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400598 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800599 cmdStr = "links"
600 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400601 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800602 except TypeError:
603 main.log.exception( self.name + ": Object not as expected" )
604 return None
Jon Halle8217482014-10-17 13:49:14 -0400605 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800606 main.log.error( self.name + ": EOF exception found" )
607 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400608 main.cleanup()
609 main.exit()
610 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800611 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400612 main.cleanup()
613 main.exit()
614
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800616 """
Jon Halle8217482014-10-17 13:49:14 -0400617 Lists all ports
618 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800620 """
Jon Halle8217482014-10-17 13:49:14 -0400621 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 if jsonFormat:
623 cmdStr = "ports -j"
624 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800625 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800626 handle variable here contains some ANSI escape color code
627 sequences at the end which are invisible in the print command
628 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800629 function. The repr( handle ) output when printed shows the ANSI
630 escape sequences. In json.loads( somestring ), this somestring
631 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800632 fail with the escape sequence. So we take off that escape
633 sequence using the following commads:
634
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
636 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800637 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800638 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
639 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400640 return handle1
641
Jon Halle8217482014-10-17 13:49:14 -0400642 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 cmdStr = "ports"
644 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800645 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800646 except TypeError:
647 main.log.exception( self.name + ": Object not as expected" )
648 return None
Jon Halle8217482014-10-17 13:49:14 -0400649 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800650 main.log.error( self.name + ": EOF exception found" )
651 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400652 main.cleanup()
653 main.exit()
654 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800655 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400656 main.cleanup()
657 main.exit()
658
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800660 """
Jon Hall983a1702014-10-28 18:44:22 -0400661 Lists all devices and the controllers with roles assigned to them
662 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800663 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800664 """
andrewonlab7c211572014-10-15 16:45:20 -0400665 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 if jsonFormat:
667 cmdStr = "roles -j"
668 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800669 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800670 handle variable here contains some ANSI escape color code
671 sequences at the end which are invisible in the print command
672 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800673 function. The repr( handle ) output when printed shows the ANSI
674 escape sequences. In json.loads( somestring ), this somestring
675 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800676 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500677
Jon Halle3f39ff2015-01-13 11:50:53 -0800678 So we take off that escape sequence using the following
679 commads:
680
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
682 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800683 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
685 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400686 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400687
andrewonlab7c211572014-10-15 16:45:20 -0400688 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 cmdStr = "roles"
690 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800691 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800692 except TypeError:
693 main.log.exception( self.name + ": Object not as expected" )
694 return None
Jon Hall983a1702014-10-28 18:44:22 -0400695 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800696 main.log.error( self.name + ": EOF exception found" )
697 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400698 main.cleanup()
699 main.exit()
700 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800701 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400702 main.cleanup()
703 main.exit()
704
kelvin-onlabd3b64892015-01-20 13:26:24 -0800705 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800706 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800707 Given the a string containing the json representation of the "roles"
708 cli command and a partial or whole device id, returns a json object
709 containing the roles output for the first device whose id contains
710 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400711
712 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800713 A dict of the role assignments for the given device or
714 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800715 """
Jon Hall983a1702014-10-28 18:44:22 -0400716 try:
717 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800718 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400719 return None
720 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800721 rawRoles = self.roles()
722 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800723 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800725 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800726 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400727 return device
728 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800729 except TypeError:
730 main.log.exception( self.name + ": Object not as expected" )
731 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400735 main.cleanup()
736 main.exit()
737 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800738 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400739 main.cleanup()
740 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800741
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800743 """
Jon Hall94fd0472014-12-08 11:52:42 -0800744 Iterates through each device and checks if there is a master assigned
745 Returns: main.TRUE if each device has a master
746 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800747 """
Jon Hall94fd0472014-12-08 11:52:42 -0800748 try:
749 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800750 rawRoles = self.roles()
751 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800752 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800754 # print device
755 if device[ 'master' ] == "none":
756 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800757 return main.FALSE
758 return main.TRUE
759
Jon Halld4d4b372015-01-28 16:02:41 -0800760 except TypeError:
761 main.log.exception( self.name + ": Object not as expected" )
762 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800766 main.cleanup()
767 main.exit()
768 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800769 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800770 main.cleanup()
771 main.exit()
772
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800774 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400775 Returns string of paths, and the cost.
776 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800777 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400778 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800779 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
780 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800781 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( "Error in getting paths" )
783 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400784 else:
kelvin8ec71442015-01-15 16:57:00 -0800785 path = handle.split( ";" )[ 0 ]
786 cost = handle.split( ";" )[ 1 ]
787 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800788 except TypeError:
789 main.log.exception( self.name + ": Object not as expected" )
790 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800792 main.log.error( self.name + ": EOF exception found" )
793 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400794 main.cleanup()
795 main.exit()
796 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800797 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400798 main.cleanup()
799 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800800
kelvin-onlabd3b64892015-01-20 13:26:24 -0800801 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800802 """
Jon Hallffb386d2014-11-21 13:43:38 -0800803 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400804 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800806 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400807 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 if jsonFormat:
809 cmdStr = "hosts -j"
810 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800811 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800812 handle variable here contains some ANSI escape color code
813 sequences at the end which are invisible in the print command
814 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800815 function. The repr( handle ) output when printed shows the ANSI
816 escape sequences. In json.loads( somestring ), this somestring
817 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800818 fail with the escape sequence. So we take off that escape
819 sequence using:
820
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
822 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800823 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800824 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
825 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400826 return handle1
827 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800828 cmdStr = "hosts"
829 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400830 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800831 except TypeError:
832 main.log.exception( self.name + ": Object not as expected" )
833 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800835 main.log.error( self.name + ": EOF exception found" )
836 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400837 main.cleanup()
838 main.exit()
839 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800840 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400841 main.cleanup()
842 main.exit()
843
kelvin-onlabd3b64892015-01-20 13:26:24 -0800844 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800845 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400846 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800847
848 Note: mac must be a colon seperated mac address, but could be a
849 partial mac address
850
Jon Hall42db6dc2014-10-24 19:03:48 -0400851 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800852 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400853 import json
854 try:
kelvin8ec71442015-01-15 16:57:00 -0800855 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400856 return None
857 else:
858 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 rawHosts = self.hosts()
860 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800861 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800862 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800863 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800864 if not host:
865 pass
866 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400867 return host
868 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800869 except TypeError:
870 main.log.exception( self.name + ": Object not as expected" )
871 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800873 main.log.error( self.name + ": EOF exception found" )
874 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400875 main.cleanup()
876 main.exit()
877 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800878 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400879 main.cleanup()
880 main.exit()
881
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800883 """
884 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400885 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800886
andrewonlab3f0a4af2014-10-17 12:25:14 -0400887 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400889 IMPORTANT:
890 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800891 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400892 Furthermore, it assumes that value of VLAN is '-1'
893 Description:
kelvin8ec71442015-01-15 16:57:00 -0800894 Converts mininet hosts ( h1, h2, h3... ) into
895 ONOS format ( 00:00:00:00:00:01/-1 , ... )
896 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400897 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800898 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400899
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800901 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 hostHex = hex( int( host ) ).zfill( 12 )
903 hostHex = str( hostHex ).replace( 'x', '0' )
904 i = iter( str( hostHex ) )
905 hostHex = ":".join( a + b for a, b in zip( i, i ) )
906 hostHex = hostHex + "/-1"
907 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908
kelvin-onlabd3b64892015-01-20 13:26:24 -0800909 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400910
Jon Halld4d4b372015-01-28 16:02:41 -0800911 except TypeError:
912 main.log.exception( self.name + ": Object not as expected" )
913 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800915 main.log.error( self.name + ": EOF exception found" )
916 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400917 main.cleanup()
918 main.exit()
919 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800920 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400921 main.cleanup()
922 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
andrewonlabe6745342014-10-17 14:29:13 -0400926 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800927 * hostIdOne: ONOS host id for host1
928 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400929 Description:
kelvin8ec71442015-01-15 16:57:00 -0800930 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500931 specifying the two hosts.
kelvin8ec71442015-01-15 16:57:00 -0800932 """
andrewonlabe6745342014-10-17 14:29:13 -0400933 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800934 cmdStr = "add-host-intent " + str( hostIdOne ) +\
935 " " + str( hostIdTwo )
936 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800937 if re.search( "Error", handle ):
938 main.log.error( "Error in adding Host intent" )
939 return handle
940 else:
941 main.log.info( "Host intent installed between " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800943 return main.TRUE
944
Jon Halld4d4b372015-01-28 16:02:41 -0800945 except TypeError:
946 main.log.exception( self.name + ": Object not as expected" )
947 return None
Hari Krishnaccfb0d52015-02-19 09:38:29 -0800948
andrewonlabe6745342014-10-17 14:29:13 -0400949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800950 main.log.error( self.name + ": EOF exception found" )
951 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400952 main.cleanup()
953 main.exit()
954 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800955 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400956 main.cleanup()
957 main.exit()
958
kelvin-onlabd3b64892015-01-20 13:26:24 -0800959 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800960 """
andrewonlab7b31d232014-10-24 13:31:47 -0400961 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 * ingressDevice: device id of ingress device
963 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400964 Optional:
965 TODO: Still needs to be implemented via dev side
kelvin-onlab898a6c62015-01-16 14:13:53 -0800966 """
andrewonlab7b31d232014-10-24 13:31:47 -0400967 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
969 " " + str( egressDevice )
970 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800971 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800972 if re.search( "Error", handle ):
andrewonlab7b31d232014-10-24 13:31:47 -0400973 return handle
974 else:
975 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800976 except TypeError:
977 main.log.exception( self.name + ": Object not as expected" )
978 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400982 main.cleanup()
983 main.exit()
984 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800985 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400986 main.cleanup()
987 main.exit()
988
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -0800990 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 ingressDevice,
992 egressDevice,
993 portIngress="",
994 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800995 ethType="",
996 ethSrc="",
997 ethDst="",
998 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001000 ipProto="",
1001 ipSrc="",
1002 ipDst="",
1003 tcpSrc="",
1004 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001006 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 * ingressDevice: device id of ingress device
1008 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001009 Optional:
1010 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001011 * ethSrc: specify ethSrc ( i.e. src mac addr )
1012 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001013 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001015 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001016 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001017 * ipSrc: specify ip source address
1018 * ipDst: specify ip destination address
1019 * tcpSrc: specify tcp source port
1020 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001021 Description:
kelvin8ec71442015-01-15 16:57:00 -08001022 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001023 specifying device id's and optional fields
1024
Jon Halle3f39ff2015-01-13 11:50:53 -08001025 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001026 options developers provide for point-to-point
1027 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001028 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001029 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001030 cmd = ""
1031
kelvin8ec71442015-01-15 16:57:00 -08001032 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001033 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001035 and not ipProto and not ipSrc and not ipDst \
1036 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001037 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001038
andrewonlab289e4b72014-10-21 21:24:18 -04001039 else:
andrewonlab36af3822014-11-18 17:48:18 -05001040 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001041
andrewonlab0c0a6772014-10-22 12:31:18 -04001042 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001043 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001044 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001045 cmd += " --ethSrc " + str( ethSrc )
1046 if ethDst:
1047 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001048 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001049 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001050 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001051 cmd += " --lambda "
1052 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001053 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001054 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001055 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001056 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001057 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001058 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001059 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001060 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001061 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001062
kelvin8ec71442015-01-15 16:57:00 -08001063 # Check whether the user appended the port
1064 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001065 if "/" in ingressDevice:
1066 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001067 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 if not portIngress:
kelvin8ec71442015-01-15 16:57:00 -08001069 main.log.error( "You must specify " +
1070 "the ingress port" )
1071 # TODO: perhaps more meaningful return
andrewonlab36af3822014-11-18 17:48:18 -05001072 return main.FALSE
1073
kelvin8ec71442015-01-15 16:57:00 -08001074 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 str( ingressDevice ) + "/" +\
1076 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 if "/" in egressDevice:
1079 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001080 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001081 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001082 main.log.error( "You must specify " +
1083 "the egress port" )
andrewonlab36af3822014-11-18 17:48:18 -05001084 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001085
kelvin8ec71442015-01-15 16:57:00 -08001086 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 str( egressDevice ) + "/" +\
1088 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001089
kelvin-onlab898a6c62015-01-16 14:13:53 -08001090 handle = self.sendline( cmd )
1091 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001092 main.log.error( "Error in adding point-to-point intent" )
Jon Hall47a93fb2015-01-06 16:46:06 -08001093 return main.FALSE
andrewonlab4dbb4d82014-10-17 18:22:31 -04001094 else:
1095 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001096 except TypeError:
1097 main.log.exception( self.name + ": Object not as expected" )
1098 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001102 main.cleanup()
1103 main.exit()
1104 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001105 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001106 main.cleanup()
1107 main.exit()
1108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001110 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 ingressDevice1,
1112 ingressDevice2,
1113 egressDevice,
1114 portIngress="",
1115 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001116 ethType="",
1117 ethSrc="",
1118 ethDst="",
1119 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001121 ipProto="",
1122 ipSrc="",
1123 ipDst="",
1124 tcpSrc="",
1125 tcpDst="",
1126 setEthSrc="",
1127 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001128 """
shahshreyad0c80432014-12-04 16:56:05 -08001129 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001130 This function assumes that there would be 2 ingress devices and
1131 one egress device. For more number of ingress devices, this
1132 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001133 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 * ingressDevice1: device id of ingress device1
1135 * ingressDevice2: device id of ingress device2
1136 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001137 Optional:
1138 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001139 * ethSrc: specify ethSrc ( i.e. src mac addr )
1140 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001141 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001143 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001144 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001145 * ipSrc: specify ip source address
1146 * ipDst: specify ip destination address
1147 * tcpSrc: specify tcp source port
1148 * tcpDst: specify tcp destination port
1149 * setEthSrc: action to Rewrite Source MAC Address
1150 * setEthDst: action to Rewrite Destination MAC Address
1151 Description:
kelvin8ec71442015-01-15 16:57:00 -08001152 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001153 specifying device id's and optional fields
1154
Jon Halle3f39ff2015-01-13 11:50:53 -08001155 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001156 options developers provide for multipointpoint-to-singlepoint
1157 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001158 """
shahshreyad0c80432014-12-04 16:56:05 -08001159 try:
1160 cmd = ""
1161
kelvin8ec71442015-01-15 16:57:00 -08001162 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001163 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001165 and not ipProto and not ipSrc and not ipDst\
1166 and not tcpSrc and not tcpDst and not setEthSrc\
1167 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001168 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001169
1170 else:
1171 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001172
shahshreyad0c80432014-12-04 16:56:05 -08001173 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001174 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001175 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001176 cmd += " --ethSrc " + str( ethSrc )
1177 if ethDst:
1178 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001179 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001180 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001182 cmd += " --lambda "
1183 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001184 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001185 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001186 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001187 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001188 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001189 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001190 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001191 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001192 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001193 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001194 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001195 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001196 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001197
kelvin8ec71442015-01-15 16:57:00 -08001198 # Check whether the user appended the port
1199 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 if "/" in ingressDevice1:
1201 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001202 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001203 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( "You must specify " +
1205 "the ingress port1" )
1206 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001207 return main.FALSE
1208
kelvin8ec71442015-01-15 16:57:00 -08001209 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001210 str( ingressDevice1 ) + "/" +\
1211 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001212
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 if "/" in ingressDevice2:
1214 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001215 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001217 main.log.error( "You must specify " +
1218 "the ingress port2" )
1219 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001220 return main.FALSE
1221
kelvin8ec71442015-01-15 16:57:00 -08001222 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 str( ingressDevice2 ) + "/" +\
1224 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001225
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 if "/" in egressDevice:
1227 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001228 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001230 main.log.error( "You must specify " +
1231 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001232 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001233
kelvin8ec71442015-01-15 16:57:00 -08001234 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001235 str( egressDevice ) + "/" +\
1236 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001237 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001238 handle = self.sendline( cmd )
1239 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001240 main.log.error( "Error in adding point-to-point intent" )
shahshreyad0c80432014-12-04 16:56:05 -08001241 return self.handle
1242 else:
1243 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001244 except TypeError:
1245 main.log.exception( self.name + ": Object not as expected" )
1246 return None
shahshreyad0c80432014-12-04 16:56:05 -08001247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001248 main.log.error( self.name + ": EOF exception found" )
1249 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001250 main.cleanup()
1251 main.exit()
1252 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001253 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001254 main.cleanup()
1255 main.exit()
1256
shahshreya1c818fc2015-02-26 13:44:08 -08001257 def removeIntent( self, intentId, app = 'org.onosproject.cli',
1258 purge = False, sync = False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 """
shahshreya1c818fc2015-02-26 13:44:08 -08001260 Remove intent for specified application id and intent id
1261 Optional args:-
1262 -s or --sync: Waits for the removal before returning
1263 -p or --purge: Purge the intent from the store after removal
1264
Jon Halle3f39ff2015-01-13 11:50:53 -08001265 Returns:
1266 main.False on error and
1267 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001268 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001269 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001270 cmdStr = "remove-intent "
1271 if purge:
1272 cmdStr += " -p"
1273 if sync:
1274 cmdStr += " -s"
1275
1276 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001278 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001279 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001280 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001281 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001282 # TODO: Should this be main.TRUE
1283 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001284 except TypeError:
1285 main.log.exception( self.name + ": Object not as expected" )
1286 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001287 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001288 main.log.error( self.name + ": EOF exception found" )
1289 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001290 main.cleanup()
1291 main.exit()
1292 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001293 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001294 main.cleanup()
1295 main.exit()
1296
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001298 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001299 NOTE: This method should be used after installing application:
1300 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001301 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001303 Description:
1304 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001305 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001306 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 if jsonFormat:
1308 cmdStr = "routes -j"
1309 handleTmp = self.sendline( cmdStr )
1310 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1311 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001312 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 cmdStr = "routes"
1314 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001315 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001316 except TypeError:
1317 main.log.exception( self.name + ": Object not as expected" )
1318 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001319 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001320 main.log.error( self.name + ": EOF exception found" )
1321 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001322 main.cleanup()
1323 main.exit()
1324 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001325 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001326 main.cleanup()
1327 main.exit()
1328
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001330 """
andrewonlab377693f2014-10-21 16:00:30 -04001331 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001332 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001333 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001334 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001335 """
andrewonlabe6745342014-10-17 14:29:13 -04001336 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001337 if jsonFormat:
1338 cmdStr = "intents -j"
1339 handle = self.sendline( cmdStr )
1340 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1341 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001342 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 cmdStr = "intents"
1344 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001345 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001346 except TypeError:
1347 main.log.exception( self.name + ": Object not as expected" )
1348 return None
andrewonlabe6745342014-10-17 14:29:13 -04001349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001350 main.log.error( self.name + ": EOF exception found" )
1351 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001352 main.cleanup()
1353 main.exit()
1354 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001355 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001356 main.cleanup()
1357 main.exit()
1358
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001360 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001361 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001363 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001364 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001366 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 if jsonFormat:
1368 cmdStr = "flows -j"
1369 handle = self.sendline( cmdStr )
1370 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1371 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001372 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001373 cmdStr = "flows"
1374 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001375 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001376 main.log.error( self.name + ".flows() response: " +
1377 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001378 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001379 except TypeError:
1380 main.log.exception( self.name + ": Object not as expected" )
1381 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001382 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001383 main.log.error( self.name + ": EOF exception found" )
1384 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001385 main.cleanup()
1386 main.exit()
1387 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001388 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001389 main.cleanup()
1390 main.exit()
1391
kelvin-onlabd3b64892015-01-20 13:26:24 -08001392 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1393 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001394 """
andrewonlab87852b02014-11-19 18:44:19 -05001395 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001396 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001397 a specific point-to-point intent definition
1398 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 * dpidSrc: specify source dpid
1400 * dpidDst: specify destination dpid
1401 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001402 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001404 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001406 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001407 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001408 """
andrewonlab87852b02014-11-19 18:44:19 -05001409 try:
kelvin8ec71442015-01-15 16:57:00 -08001410 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1412 str( numIntents )
1413 if numMult:
1414 cmd += " " + str( numMult )
1415 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001416 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001417 if appId:
1418 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001419 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1421 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001422 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001424 main.log.info( handle )
1425 # Split result by newline
1426 newline = handle.split( "\r\r\n" )
1427 # Ignore the first object of list, which is empty
1428 newline = newline[ 1: ]
1429 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001430 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001431 result = result.split( ": " )
1432 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1434 main.log.info( latResult )
1435 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001436 else:
1437 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001438 except TypeError:
1439 main.log.exception( self.name + ": Object not as expected" )
1440 return None
andrewonlab87852b02014-11-19 18:44:19 -05001441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001442 main.log.error( self.name + ": EOF exception found" )
1443 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001444 main.cleanup()
1445 main.exit()
1446 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001447 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001448 main.cleanup()
1449 main.exit()
1450
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001452 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001453 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001454 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001456 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001457 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 if jsonFormat:
1459 cmdStr = "intents-events-metrics -j"
1460 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001461 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001462 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1463 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001464 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 cmdStr = "intents-events-metrics"
1466 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001467 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001468 except TypeError:
1469 main.log.exception( self.name + ": Object not as expected" )
1470 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001472 main.log.error( self.name + ": EOF exception found" )
1473 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001474 main.cleanup()
1475 main.exit()
1476 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001477 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001478 main.cleanup()
1479 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001480
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001482 """
1483 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001484 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001485 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001486 """
andrewonlab867212a2014-10-22 20:13:38 -04001487 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 if jsonFormat:
1489 cmdStr = "topology-events-metrics -j"
1490 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001491 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1493 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001494 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 cmdStr = "topology-events-metrics"
1496 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001497 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001498 except TypeError:
1499 main.log.exception( self.name + ": Object not as expected" )
1500 return None
andrewonlab867212a2014-10-22 20:13:38 -04001501 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001504 main.cleanup()
1505 main.exit()
1506 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001507 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001508 main.cleanup()
1509 main.exit()
1510
kelvin8ec71442015-01-15 16:57:00 -08001511 # Wrapper functions ****************
1512 # Wrapper functions use existing driver
1513 # functions and extends their use case.
1514 # For example, we may use the output of
1515 # a normal driver function, and parse it
1516 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001517
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001519 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001520 Description:
1521 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001522 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001523 try:
kelvin8ec71442015-01-15 16:57:00 -08001524 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 intentsStr = self.intents()
1526 allIntentList = []
1527 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001528
kelvin8ec71442015-01-15 16:57:00 -08001529 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1531 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001532 if "onos>" in intents:
1533 continue
1534 elif "intents" in intents:
1535 continue
1536 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 lineList = intents.split( " " )
1538 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001539
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001541
kelvin-onlabd3b64892015-01-20 13:26:24 -08001542 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001543 if not intents:
1544 continue
1545 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001547
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001549
Jon Halld4d4b372015-01-28 16:02:41 -08001550 except TypeError:
1551 main.log.exception( self.name + ": Object not as expected" )
1552 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001553 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001554 main.log.error( self.name + ": EOF exception found" )
1555 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001556 main.cleanup()
1557 main.exit()
1558 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001559 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001560 main.cleanup()
1561 main.exit()
1562
shahshreya353268a2015-02-25 17:03:41 -08001563
shahshreya580840d2015-02-26 10:44:04 -08001564 def FlowAddedCount( self, id ):
shahshreya353268a2015-02-25 17:03:41 -08001565 """
1566 Determine the number of flow rules for the given device id that are
1567 in the added state
1568 """
1569 try:
1570 cmdStr = "flows any " + id + " | grep 'state=ADDED' | wc -l"
1571 handle = self.sendline( cmdStr )
1572 return handle
1573 except pexpect.EOF:
1574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
1576 main.cleanup()
1577 main.exit()
1578 except:
1579 main.log.exception( self.name + ": Uncaught exception!" )
1580 main.cleanup()
1581 main.exit()
1582
1583
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001585 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001586 Use 'devices' function to obtain list of all devices
1587 and parse the result to obtain a list of all device
1588 id's. Returns this list. Returns empty list if no
1589 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001590 List is ordered sequentially
1591
andrewonlab3e15ead2014-10-15 14:21:34 -04001592 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001593 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001594 the ids. By obtaining the list of device ids on the fly,
1595 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001596 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001597 try:
kelvin8ec71442015-01-15 16:57:00 -08001598 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 devicesStr = self.devices( jsonFormat=False )
1600 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001601
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001603 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 return idList
kelvin8ec71442015-01-15 16:57:00 -08001605
1606 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001608 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001610 # Split list further into arguments before and after string
1611 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 # append to idList
1613 for arg in tempList:
1614 idList.append( arg.split( "id=" )[ 1 ] )
1615 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001616
Jon Halld4d4b372015-01-28 16:02:41 -08001617 except TypeError:
1618 main.log.exception( self.name + ": Object not as expected" )
1619 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001620 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001621 main.log.error( self.name + ": EOF exception found" )
1622 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001623 main.cleanup()
1624 main.exit()
1625 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001626 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001627 main.cleanup()
1628 main.exit()
1629
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001631 """
andrewonlab7c211572014-10-15 16:45:20 -04001632 Uses 'nodes' function to obtain list of all nodes
1633 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001634 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001635 Returns:
1636 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001637 """
andrewonlab7c211572014-10-15 16:45:20 -04001638 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001639 nodesStr = self.nodes()
1640 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001641
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001643 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001644 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001645
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001647 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001648
kelvin8ec71442015-01-15 16:57:00 -08001649 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001650 nodesList = nodesStr.split( "," )
1651 tempList = [ node for node in nodesList if "id=" in node ]
1652 for arg in tempList:
1653 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001654
kelvin-onlabd3b64892015-01-20 13:26:24 -08001655 return idList
kelvin8ec71442015-01-15 16:57:00 -08001656
Jon Halld4d4b372015-01-28 16:02:41 -08001657 except TypeError:
1658 main.log.exception( self.name + ": Object not as expected" )
1659 return None
andrewonlab7c211572014-10-15 16:45:20 -04001660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001661 main.log.error( self.name + ": EOF exception found" )
1662 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001663 main.cleanup()
1664 main.exit()
1665 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001666 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001667 main.cleanup()
1668 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001669
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001671 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001672 Return the first device from the devices api whose 'id' contains 'dpid'
1673 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001674 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001675 import json
1676 try:
kelvin8ec71442015-01-15 16:57:00 -08001677 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001678 return None
1679 else:
kelvin8ec71442015-01-15 16:57:00 -08001680 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001681 rawDevices = self.devices()
1682 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001683 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001685 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1686 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001687 return device
1688 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001689 except TypeError:
1690 main.log.exception( self.name + ": Object not as expected" )
1691 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001695 main.cleanup()
1696 main.exit()
1697 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001698 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001699 main.cleanup()
1700 main.exit()
1701
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001703 """
1704 Checks the number of swithes & links that ONOS sees against the
1705 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001706 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001707
Jon Hall42db6dc2014-10-24 19:03:48 -04001708 Params: ip = ip used for the onos cli
1709 numoswitch = expected number of switches
1710 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 logLevel = level to log to. Currently accepts
1712 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001713
1714
kelvin-onlabd3b64892015-01-20 13:26:24 -08001715 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001716
kelvin8ec71442015-01-15 16:57:00 -08001717 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001718 main.FALSE if the numer of switches and links is incorrect,
1719 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001720 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001721 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001723 if topology == {}:
1724 return main.ERROR
1725 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001726 # Is the number of switches is what we expected
1727 devices = topology.get( 'devices', False )
1728 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001729 if devices == False or links == False:
1730 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001732 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 linkCheck = ( int( links ) == int( numolink ) )
1734 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001735 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001736 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001737 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001738 result = main.TRUE
1739 else:
1740 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 "The number of links and switches does not matc\
1742 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001743 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001744 output = output + "\n ONOS sees %i devices (%i expected) \
1745 and %i links (%i expected)" % (
1746 int( devices ), int( numoswitch ), int( links ),
1747 int( numolink ) )
1748 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001749 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001750 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001751 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001752 else:
kelvin8ec71442015-01-15 16:57:00 -08001753 main.log.info( output )
1754 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001755 except TypeError:
1756 main.log.exception( self.name + ": Object not as expected" )
1757 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001759 main.log.error( self.name + ": EOF exception found" )
1760 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001761 main.cleanup()
1762 main.exit()
1763 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001764 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001765 main.cleanup()
1766 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001767
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001769 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001770 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001771 deviceId must be the id of a device as seen in the onos devices command
1772 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001773 role must be either master, standby, or none
1774
Jon Halle3f39ff2015-01-13 11:50:53 -08001775 Returns:
1776 main.TRUE or main.FALSE based on argument verification and
1777 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001778 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001779 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001780 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001781 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001782 cmdStr = "device-role " +\
1783 str( deviceId ) + " " +\
1784 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001785 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001787 if re.search( "Error", handle ):
1788 # end color output to escape any colours
1789 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001790 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001791 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001792 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001793 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001794 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001795 main.log.error( "Invalid 'role' given to device_role(). " +
1796 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001797 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001798 except TypeError:
1799 main.log.exception( self.name + ": Object not as expected" )
1800 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001801 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001802 main.log.error( self.name + ": EOF exception found" )
1803 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001804 main.cleanup()
1805 main.exit()
1806 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001807 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001808 main.cleanup()
1809 main.exit()
1810
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001812 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001813 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001814 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001816 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001817 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001818 if jsonFormat:
1819 cmdStr = "clusters -j"
1820 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001821 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001822 handle variable here contains some ANSI escape color code
1823 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001824 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001825 function. The repr( handle ) output when printed shows the ANSI
1826 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001827 variable is actually repr( somestring ) and json.loads would
1828 fail with the escape sequence. So we take off that escape
1829 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001830
kelvin-onlabd3b64892015-01-20 13:26:24 -08001831 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1832 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001833 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001834 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1835 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001836 return handle1
1837 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001838 cmdStr = "clusters"
1839 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001840 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001841 except TypeError:
1842 main.log.exception( self.name + ": Object not as expected" )
1843 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001844 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001845 main.log.error( self.name + ": EOF exception found" )
1846 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001847 main.cleanup()
1848 main.exit()
1849 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001850 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001851 main.cleanup()
1852 main.exit()
1853
kelvin-onlabd3b64892015-01-20 13:26:24 -08001854 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001855 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001856 CLI command to get the current leader for the Election test application
1857 NOTE: Requires installation of the onos-app-election feature
1858 Returns: Node IP of the leader if one exists
1859 None if none exists
1860 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 """
Jon Hall94fd0472014-12-08 11:52:42 -08001862 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001863 cmdStr = "election-test-leader"
1864 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001865 # Leader
1866 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001867 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 nodeSearch = re.search( leaderPattern, response )
1869 if nodeSearch:
1870 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001873 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001874 # no leader
1875 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001876 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001877 nullSearch = re.search( nullPattern, response )
1878 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001879 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001880 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001881 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001883 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001884 if re.search( errorPattern, response ):
1885 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001886 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001887 return main.FALSE
1888 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001889 main.log.error( "Error in election_test_leader: " +
1890 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001891 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001892 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001893 except TypeError:
1894 main.log.exception( self.name + ": Object not as expected" )
1895 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001896 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001897 main.log.error( self.name + ": EOF exception found" )
1898 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001899 main.cleanup()
1900 main.exit()
1901 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001902 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001903 main.cleanup()
1904 main.exit()
1905
kelvin-onlabd3b64892015-01-20 13:26:24 -08001906 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001907 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001908 CLI command to run for leadership of the Election test application.
1909 NOTE: Requires installation of the onos-app-election feature
1910 Returns: Main.TRUE on success
1911 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001912 """
Jon Hall94fd0472014-12-08 11:52:42 -08001913 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001914 cmdStr = "election-test-run"
1915 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001916 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001917 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001918 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001919 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001920 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001921 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001922 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001923 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001924 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001925 errorPattern = "Command\snot\sfound"
1926 if re.search( errorPattern, response ):
1927 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001928 return main.FALSE
1929 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001930 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001931 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001932 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001933 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001934 except TypeError:
1935 main.log.exception( self.name + ": Object not as expected" )
1936 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001937 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001938 main.log.error( self.name + ": EOF exception found" )
1939 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001940 main.cleanup()
1941 main.exit()
1942 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001943 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001944 main.cleanup()
1945 main.exit()
1946
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001948 """
Jon Hall94fd0472014-12-08 11:52:42 -08001949 * CLI command to withdraw the local node from leadership election for
1950 * the Election test application.
1951 #NOTE: Requires installation of the onos-app-election feature
1952 Returns: Main.TRUE on success
1953 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001954 """
Jon Hall94fd0472014-12-08 11:52:42 -08001955 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001956 cmdStr = "election-test-withdraw"
1957 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001958 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001959 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001961 if re.search( successPattern, response ):
1962 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001963 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001964 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001965 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001966 errorPattern = "Command\snot\sfound"
1967 if re.search( errorPattern, response ):
1968 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001969 return main.FALSE
1970 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001971 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001972 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001973 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001974 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001975 except TypeError:
1976 main.log.exception( self.name + ": Object not as expected" )
1977 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001979 main.log.error( self.name + ": EOF exception found" )
1980 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001981 main.cleanup()
1982 main.exit()
1983 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001984 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001985 main.cleanup()
1986 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001987
kelvin8ec71442015-01-15 16:57:00 -08001988 def getDevicePortsEnabledCount( self, dpid ):
1989 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001990 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001991 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001992 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001993 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001994 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1995 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001996 if re.search( "No such device", output ):
1997 main.log.error( "Error in getting ports" )
1998 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001999 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002000 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002001 except TypeError:
2002 main.log.exception( self.name + ": Object not as expected" )
2003 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002007 main.cleanup()
2008 main.exit()
2009 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002010 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002011 main.cleanup()
2012 main.exit()
2013
kelvin8ec71442015-01-15 16:57:00 -08002014 def getDeviceLinksActiveCount( self, dpid ):
2015 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002016 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002017 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002018 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002019 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002020 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2021 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002022 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 main.log.error( "Error in getting ports " )
2024 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002025 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002026 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002027 except TypeError:
2028 main.log.exception( self.name + ": Object not as expected" )
2029 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002030 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002031 main.log.error( self.name + ": EOF exception found" )
2032 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002033 main.cleanup()
2034 main.exit()
2035 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002036 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002037 main.cleanup()
2038 main.exit()
2039
kelvin8ec71442015-01-15 16:57:00 -08002040 def getAllIntentIds( self ):
2041 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002042 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002043 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002044 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002045 cmdStr = "onos:intents | grep id="
2046 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002047 if re.search( "Error", output ):
2048 main.log.error( "Error in getting ports" )
2049 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002050 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002051 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002052 except TypeError:
2053 main.log.exception( self.name + ": Object not as expected" )
2054 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002055 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002056 main.log.error( self.name + ": EOF exception found" )
2057 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002058 main.cleanup()
2059 main.exit()
2060 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002061 main.log.exception( self.name + ": Uncaught exception!" )
2062 main.cleanup()
2063 main.exit()
2064
Jon Hall3f45d112015-02-24 16:42:56 -08002065 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002066 """
Jon Hall3f45d112015-02-24 16:42:56 -08002067 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002068 """
Jon Halld4d4b372015-01-28 16:02:41 -08002069 try:
Jon Hall3f45d112015-02-24 16:42:56 -08002070 intents = self.intents( )
2071 intentStates = []
2072 out = []
2073 for intent in json.loads( intents ):
2074 intentStates.append( intent.get( 'state', None ) )
2075 for i in set( intentStates ):
2076 out.append( (i, intentStates.count( i ) ) )
2077 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002078 except TypeError:
2079 main.log.exception( self.name + ": Object not as expected" )
2080 return None
2081 except pexpect.EOF:
2082 main.log.error( self.name + ": EOF exception found" )
2083 main.log.error( self.name + ": " + self.handle.before )
2084 main.cleanup()
2085 main.exit()
2086 except:
2087 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002088 main.cleanup()
2089 main.exit()