blob: 991f203294ff8bd441c8b6c403426bcbea66f340 [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-onlab54400a92015-02-26 18:05:51 -08001359 def getIntentState(self, intentsId, intentsJson=None):
1360 """
1361 Description:
1362 Check intent state.
1363 Accepts a single intent ID (string type) or a list of intent IDs.
1364 Returns the state(string type) of the id if a single intent ID is
1365 accepted.
1366 Returns a dictionary with intent IDs as the key and its corresponding
1367 states as the values
1368 values
1369 Required:
1370 intentId: intent ID (string type)
1371 intentsJson: parsed json object from the onos:intents api
1372 Returns:
1373 state = An intent's state- INSTALL,WITHDRAWN etc.
1374 stateDict = Dictionary of intent's state. intent ID as the keys and
1375 state as the values.
1376 """
1377 import json
1378 import types
1379 try:
1380 state = "State is Undefined"
1381 if not intentsJson:
1382 intentsJsonTemp = json.loads(self.intents())
1383 else:
1384 intentsJsonTemp = json.loads(intentsJson)
1385 if isinstance(intentsId,types.StringType):
1386 for intent in intentsJsonTemp:
1387 if intentsId == intent['id']:
1388 state = intent['state']
1389 return state
1390 main.log.info("Cannot find intent ID" + str(intentsId) +" on the list")
1391 return state
1392 elif isinstance(intentsId,types.ListType):
1393 stateDict = {}
1394 for ID in intentsId:
1395 for intents in intentsJsonTemp:
1396 if ID == intents['id']:
1397 stateDict[ID] = intents['state']
1398 break
1399 if len(intentsId) != len(stateDict):
1400 main.log.info("Cannot find some of the intent ID state")
1401 return stateDict
1402 else:
1403 main.log.info("Invalid intents ID entry")
1404 return None
1405 main.log.info("Something went wrong getting intent ID state")
1406 return None
1407 except TypeError:
1408 main.log.exception( self.name + ": Object not as expected" )
1409 return None
1410 except pexpect.EOF:
1411 main.log.error( self.name + ": EOF exception found" )
1412 main.log.error( self.name + ": " + self.handle.before )
1413 main.cleanup()
1414 main.exit()
1415 except:
1416 main.log.exception( self.name + ": Uncaught exception!" )
1417 main.cleanup()
1418 main.exit()
1419
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001421 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001422 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001424 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001425 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001426 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001427 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 if jsonFormat:
1429 cmdStr = "flows -j"
1430 handle = self.sendline( cmdStr )
1431 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1432 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001433 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 cmdStr = "flows"
1435 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001436 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001437 main.log.error( self.name + ".flows() response: " +
1438 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001439 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001440 except TypeError:
1441 main.log.exception( self.name + ": Object not as expected" )
1442 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001443 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001444 main.log.error( self.name + ": EOF exception found" )
1445 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001446 main.cleanup()
1447 main.exit()
1448 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001449 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001450 main.cleanup()
1451 main.exit()
1452
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1454 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001455 """
andrewonlab87852b02014-11-19 18:44:19 -05001456 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001457 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001458 a specific point-to-point intent definition
1459 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 * dpidSrc: specify source dpid
1461 * dpidDst: specify destination dpid
1462 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001463 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001465 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001467 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001468 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001469 """
andrewonlab87852b02014-11-19 18:44:19 -05001470 try:
kelvin8ec71442015-01-15 16:57:00 -08001471 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1473 str( numIntents )
1474 if numMult:
1475 cmd += " " + str( numMult )
1476 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001477 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 if appId:
1479 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001480 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1482 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001483 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001485 main.log.info( handle )
1486 # Split result by newline
1487 newline = handle.split( "\r\r\n" )
1488 # Ignore the first object of list, which is empty
1489 newline = newline[ 1: ]
1490 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001491 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001492 result = result.split( ": " )
1493 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1495 main.log.info( latResult )
1496 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001497 else:
1498 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001499 except TypeError:
1500 main.log.exception( self.name + ": Object not as expected" )
1501 return None
andrewonlab87852b02014-11-19 18:44:19 -05001502 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001503 main.log.error( self.name + ": EOF exception found" )
1504 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001505 main.cleanup()
1506 main.exit()
1507 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001508 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001509 main.cleanup()
1510 main.exit()
1511
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001513 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001514 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001515 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001517 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001518 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 if jsonFormat:
1520 cmdStr = "intents-events-metrics -j"
1521 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001522 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1524 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001525 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 cmdStr = "intents-events-metrics"
1527 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001528 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001529 except TypeError:
1530 main.log.exception( self.name + ": Object not as expected" )
1531 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001532 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001533 main.log.error( self.name + ": EOF exception found" )
1534 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001535 main.cleanup()
1536 main.exit()
1537 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001538 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001539 main.cleanup()
1540 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001541
kelvin-onlabd3b64892015-01-20 13:26:24 -08001542 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001543 """
1544 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001545 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001547 """
andrewonlab867212a2014-10-22 20:13:38 -04001548 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 if jsonFormat:
1550 cmdStr = "topology-events-metrics -j"
1551 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001553 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1554 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001555 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001556 cmdStr = "topology-events-metrics"
1557 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001558 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001559 except TypeError:
1560 main.log.exception( self.name + ": Object not as expected" )
1561 return None
andrewonlab867212a2014-10-22 20:13:38 -04001562 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001563 main.log.error( self.name + ": EOF exception found" )
1564 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001565 main.cleanup()
1566 main.exit()
1567 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001568 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001569 main.cleanup()
1570 main.exit()
1571
kelvin8ec71442015-01-15 16:57:00 -08001572 # Wrapper functions ****************
1573 # Wrapper functions use existing driver
1574 # functions and extends their use case.
1575 # For example, we may use the output of
1576 # a normal driver function, and parse it
1577 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001578
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001580 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001581 Description:
1582 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001583 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001584 try:
kelvin8ec71442015-01-15 16:57:00 -08001585 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001586 intentsStr = self.intents()
1587 allIntentList = []
1588 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001589
kelvin8ec71442015-01-15 16:57:00 -08001590 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1592 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001593 if "onos>" in intents:
1594 continue
1595 elif "intents" in intents:
1596 continue
1597 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001598 lineList = intents.split( " " )
1599 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001600
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001602
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001604 if not intents:
1605 continue
1606 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001608
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001610
Jon Halld4d4b372015-01-28 16:02:41 -08001611 except TypeError:
1612 main.log.exception( self.name + ": Object not as expected" )
1613 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001615 main.log.error( self.name + ": EOF exception found" )
1616 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001617 main.cleanup()
1618 main.exit()
1619 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001620 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001621 main.cleanup()
1622 main.exit()
1623
shahshreya353268a2015-02-25 17:03:41 -08001624
shahshreya580840d2015-02-26 10:44:04 -08001625 def FlowAddedCount( self, id ):
shahshreya353268a2015-02-25 17:03:41 -08001626 """
1627 Determine the number of flow rules for the given device id that are
1628 in the added state
1629 """
1630 try:
1631 cmdStr = "flows any " + id + " | grep 'state=ADDED' | wc -l"
1632 handle = self.sendline( cmdStr )
1633 return handle
1634 except pexpect.EOF:
1635 main.log.error( self.name + ": EOF exception found" )
1636 main.log.error( self.name + ": " + self.handle.before )
1637 main.cleanup()
1638 main.exit()
1639 except:
1640 main.log.exception( self.name + ": Uncaught exception!" )
1641 main.cleanup()
1642 main.exit()
1643
1644
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001646 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001647 Use 'devices' function to obtain list of all devices
1648 and parse the result to obtain a list of all device
1649 id's. Returns this list. Returns empty list if no
1650 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001651 List is ordered sequentially
1652
andrewonlab3e15ead2014-10-15 14:21:34 -04001653 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001654 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001655 the ids. By obtaining the list of device ids on the fly,
1656 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001657 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001658 try:
kelvin8ec71442015-01-15 16:57:00 -08001659 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 devicesStr = self.devices( jsonFormat=False )
1661 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001662
kelvin-onlabd3b64892015-01-20 13:26:24 -08001663 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001664 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001665 return idList
kelvin8ec71442015-01-15 16:57:00 -08001666
1667 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001669 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001670 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001671 # Split list further into arguments before and after string
1672 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001673 # append to idList
1674 for arg in tempList:
1675 idList.append( arg.split( "id=" )[ 1 ] )
1676 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001677
Jon Halld4d4b372015-01-28 16:02:41 -08001678 except TypeError:
1679 main.log.exception( self.name + ": Object not as expected" )
1680 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001682 main.log.error( self.name + ": EOF exception found" )
1683 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001684 main.cleanup()
1685 main.exit()
1686 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001687 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001688 main.cleanup()
1689 main.exit()
1690
kelvin-onlabd3b64892015-01-20 13:26:24 -08001691 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001692 """
andrewonlab7c211572014-10-15 16:45:20 -04001693 Uses 'nodes' function to obtain list of all nodes
1694 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001695 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001696 Returns:
1697 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001698 """
andrewonlab7c211572014-10-15 16:45:20 -04001699 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001700 nodesStr = self.nodes()
1701 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001702
kelvin-onlabd3b64892015-01-20 13:26:24 -08001703 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001704 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001706
kelvin-onlabd3b64892015-01-20 13:26:24 -08001707 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001708 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001709
kelvin8ec71442015-01-15 16:57:00 -08001710 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 nodesList = nodesStr.split( "," )
1712 tempList = [ node for node in nodesList if "id=" in node ]
1713 for arg in tempList:
1714 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001715
kelvin-onlabd3b64892015-01-20 13:26:24 -08001716 return idList
kelvin8ec71442015-01-15 16:57:00 -08001717
Jon Halld4d4b372015-01-28 16:02:41 -08001718 except TypeError:
1719 main.log.exception( self.name + ": Object not as expected" )
1720 return None
andrewonlab7c211572014-10-15 16:45:20 -04001721 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001722 main.log.error( self.name + ": EOF exception found" )
1723 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001724 main.cleanup()
1725 main.exit()
1726 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001727 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001728 main.cleanup()
1729 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001730
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001732 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001733 Return the first device from the devices api whose 'id' contains 'dpid'
1734 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001735 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001736 import json
1737 try:
kelvin8ec71442015-01-15 16:57:00 -08001738 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001739 return None
1740 else:
kelvin8ec71442015-01-15 16:57:00 -08001741 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 rawDevices = self.devices()
1743 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001744 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001745 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001746 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1747 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001748 return device
1749 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001750 except TypeError:
1751 main.log.exception( self.name + ": Object not as expected" )
1752 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001753 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001754 main.log.error( self.name + ": EOF exception found" )
1755 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001756 main.cleanup()
1757 main.exit()
1758 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001759 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001760 main.cleanup()
1761 main.exit()
1762
kelvin-onlabd3b64892015-01-20 13:26:24 -08001763 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001764 """
1765 Checks the number of swithes & links that ONOS sees against the
1766 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001767 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001768
Jon Hall42db6dc2014-10-24 19:03:48 -04001769 Params: ip = ip used for the onos cli
1770 numoswitch = expected number of switches
1771 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 logLevel = level to log to. Currently accepts
1773 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001774
1775
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001777
kelvin8ec71442015-01-15 16:57:00 -08001778 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001779 main.FALSE if the numer of switches and links is incorrect,
1780 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001781 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001782 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001783 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001784 if topology == {}:
1785 return main.ERROR
1786 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001787 # Is the number of switches is what we expected
1788 devices = topology.get( 'devices', False )
1789 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001790 if devices == False or links == False:
1791 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001792 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001793 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001794 linkCheck = ( int( links ) == int( numolink ) )
1795 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001796 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001797 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001798 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001799 result = main.TRUE
1800 else:
1801 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001802 "The number of links and switches does not matc\
1803 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001804 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 output = output + "\n ONOS sees %i devices (%i expected) \
1806 and %i links (%i expected)" % (
1807 int( devices ), int( numoswitch ), int( links ),
1808 int( numolink ) )
1809 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001810 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001811 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001812 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001813 else:
kelvin8ec71442015-01-15 16:57:00 -08001814 main.log.info( output )
1815 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001816 except TypeError:
1817 main.log.exception( self.name + ": Object not as expected" )
1818 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001819 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001820 main.log.error( self.name + ": EOF exception found" )
1821 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001822 main.cleanup()
1823 main.exit()
1824 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001825 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001826 main.cleanup()
1827 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001828
kelvin-onlabd3b64892015-01-20 13:26:24 -08001829 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001830 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001831 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001832 deviceId must be the id of a device as seen in the onos devices command
1833 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001834 role must be either master, standby, or none
1835
Jon Halle3f39ff2015-01-13 11:50:53 -08001836 Returns:
1837 main.TRUE or main.FALSE based on argument verification and
1838 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001839 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001840 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001841 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001842 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001843 cmdStr = "device-role " +\
1844 str( deviceId ) + " " +\
1845 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001847 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001848 if re.search( "Error", handle ):
1849 # end color output to escape any colours
1850 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001851 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001852 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001853 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001854 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001855 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001856 main.log.error( "Invalid 'role' given to device_role(). " +
1857 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001858 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001859 except TypeError:
1860 main.log.exception( self.name + ": Object not as expected" )
1861 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001862 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001863 main.log.error( self.name + ": EOF exception found" )
1864 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001865 main.cleanup()
1866 main.exit()
1867 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001868 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001869 main.cleanup()
1870 main.exit()
1871
kelvin-onlabd3b64892015-01-20 13:26:24 -08001872 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001873 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001874 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001875 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001876 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001877 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001878 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001879 if jsonFormat:
1880 cmdStr = "clusters -j"
1881 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001882 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001883 handle variable here contains some ANSI escape color code
1884 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001885 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001886 function. The repr( handle ) output when printed shows the ANSI
1887 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001888 variable is actually repr( somestring ) and json.loads would
1889 fail with the escape sequence. So we take off that escape
1890 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001891
kelvin-onlabd3b64892015-01-20 13:26:24 -08001892 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1893 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001894 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001895 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1896 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001897 return handle1
1898 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 cmdStr = "clusters"
1900 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001901 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001902 except TypeError:
1903 main.log.exception( self.name + ": Object not as expected" )
1904 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001906 main.log.error( self.name + ": EOF exception found" )
1907 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001908 main.cleanup()
1909 main.exit()
1910 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001911 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001912 main.cleanup()
1913 main.exit()
1914
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001916 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001917 CLI command to get the current leader for the Election test application
1918 NOTE: Requires installation of the onos-app-election feature
1919 Returns: Node IP of the leader if one exists
1920 None if none exists
1921 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001922 """
Jon Hall94fd0472014-12-08 11:52:42 -08001923 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001924 cmdStr = "election-test-leader"
1925 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001926 # Leader
1927 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001928 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001929 nodeSearch = re.search( leaderPattern, response )
1930 if nodeSearch:
1931 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001932 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001933 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001934 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001935 # no leader
1936 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001937 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001938 nullSearch = re.search( nullPattern, response )
1939 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001940 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001941 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001942 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001943 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001944 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001945 if re.search( errorPattern, response ):
1946 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001947 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001948 return main.FALSE
1949 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001950 main.log.error( "Error in election_test_leader: " +
1951 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001952 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001953 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001957 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001960 main.cleanup()
1961 main.exit()
1962 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001963 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001964 main.cleanup()
1965 main.exit()
1966
kelvin-onlabd3b64892015-01-20 13:26:24 -08001967 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001968 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001969 CLI command to run for leadership of the Election test application.
1970 NOTE: Requires installation of the onos-app-election feature
1971 Returns: Main.TRUE on success
1972 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001973 """
Jon Hall94fd0472014-12-08 11:52:42 -08001974 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001975 cmdStr = "election-test-run"
1976 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001977 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001978 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001979 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001980 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001981 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001982 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001983 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001984 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001985 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001986 errorPattern = "Command\snot\sfound"
1987 if re.search( errorPattern, response ):
1988 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001989 return main.FALSE
1990 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001991 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001992 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001993 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001994 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001995 except TypeError:
1996 main.log.exception( self.name + ": Object not as expected" )
1997 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001998 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001999 main.log.error( self.name + ": EOF exception found" )
2000 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002001 main.cleanup()
2002 main.exit()
2003 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002004 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002005 main.cleanup()
2006 main.exit()
2007
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002009 """
Jon Hall94fd0472014-12-08 11:52:42 -08002010 * CLI command to withdraw the local node from leadership election for
2011 * the Election test application.
2012 #NOTE: Requires installation of the onos-app-election feature
2013 Returns: Main.TRUE on success
2014 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002015 """
Jon Hall94fd0472014-12-08 11:52:42 -08002016 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002017 cmdStr = "election-test-withdraw"
2018 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002019 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002020 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002021 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002022 if re.search( successPattern, response ):
2023 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002024 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002025 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002026 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002027 errorPattern = "Command\snot\sfound"
2028 if re.search( errorPattern, response ):
2029 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002030 return main.FALSE
2031 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002032 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002033 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002034 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002035 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002036 except TypeError:
2037 main.log.exception( self.name + ": Object not as expected" )
2038 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002039 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002040 main.log.error( self.name + ": EOF exception found" )
2041 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002042 main.cleanup()
2043 main.exit()
2044 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002045 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002046 main.cleanup()
2047 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002048
kelvin8ec71442015-01-15 16:57:00 -08002049 def getDevicePortsEnabledCount( self, dpid ):
2050 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002051 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002052 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002053 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002054 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002055 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2056 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002057 if re.search( "No such device", output ):
2058 main.log.error( "Error in getting ports" )
2059 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002060 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002061 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002062 except TypeError:
2063 main.log.exception( self.name + ": Object not as expected" )
2064 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002066 main.log.error( self.name + ": EOF exception found" )
2067 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002068 main.cleanup()
2069 main.exit()
2070 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002071 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002072 main.cleanup()
2073 main.exit()
2074
kelvin8ec71442015-01-15 16:57:00 -08002075 def getDeviceLinksActiveCount( self, dpid ):
2076 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002077 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002078 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002079 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002080 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002081 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2082 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002083 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002084 main.log.error( "Error in getting ports " )
2085 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002086 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002087 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002088 except TypeError:
2089 main.log.exception( self.name + ": Object not as expected" )
2090 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002091 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002092 main.log.error( self.name + ": EOF exception found" )
2093 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002094 main.cleanup()
2095 main.exit()
2096 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002097 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002098 main.cleanup()
2099 main.exit()
2100
kelvin8ec71442015-01-15 16:57:00 -08002101 def getAllIntentIds( self ):
2102 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002103 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002104 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002105 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002106 cmdStr = "onos:intents | grep id="
2107 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002108 if re.search( "Error", output ):
2109 main.log.error( "Error in getting ports" )
2110 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002111 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002112 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002113 except TypeError:
2114 main.log.exception( self.name + ": Object not as expected" )
2115 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002116 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002117 main.log.error( self.name + ": EOF exception found" )
2118 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002119 main.cleanup()
2120 main.exit()
2121 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002122 main.log.exception( self.name + ": Uncaught exception!" )
2123 main.cleanup()
2124 main.exit()
2125
Jon Hall3f45d112015-02-24 16:42:56 -08002126 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002127 """
Jon Hall3f45d112015-02-24 16:42:56 -08002128 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002129 """
Jon Halld4d4b372015-01-28 16:02:41 -08002130 try:
Jon Hall3f45d112015-02-24 16:42:56 -08002131 intents = self.intents( )
2132 intentStates = []
2133 out = []
2134 for intent in json.loads( intents ):
2135 intentStates.append( intent.get( 'state', None ) )
2136 for i in set( intentStates ):
2137 out.append( (i, intentStates.count( i ) ) )
2138 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002139 except TypeError:
2140 main.log.exception( self.name + ": Object not as expected" )
2141 return None
2142 except pexpect.EOF:
2143 main.log.error( self.name + ": EOF exception found" )
2144 main.log.error( self.name + ": " + self.handle.before )
2145 main.cleanup()
2146 main.exit()
2147 except:
2148 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002149 main.cleanup()
2150 main.exit()