blob: bfed3ebfb68138436649645d0b44b46004d1980d [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
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def removeIntent( self, intentId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001259 Remove intent for specified intent id
Jon Halle3f39ff2015-01-13 11:50:53 -08001260
1261 Returns:
1262 main.False on error and
1263 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001265 try:
shahshreyac033d022015-02-20 16:10:19 -08001266 cmdStr = "remove-intent org.onosproject.cli " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001268 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001270 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001271 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001272 # TODO: Should this be main.TRUE
1273 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001274 except TypeError:
1275 main.log.exception( self.name + ": Object not as expected" )
1276 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001277 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001278 main.log.error( self.name + ": EOF exception found" )
1279 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001280 main.cleanup()
1281 main.exit()
1282 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001283 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001284 main.cleanup()
1285 main.exit()
1286
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001288 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001289 NOTE: This method should be used after installing application:
1290 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001291 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001292 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001293 Description:
1294 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001295 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001296 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 if jsonFormat:
1298 cmdStr = "routes -j"
1299 handleTmp = self.sendline( cmdStr )
1300 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1301 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001302 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 cmdStr = "routes"
1304 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001305 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001306 except TypeError:
1307 main.log.exception( self.name + ": Object not as expected" )
1308 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001310 main.log.error( self.name + ": EOF exception found" )
1311 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001312 main.cleanup()
1313 main.exit()
1314 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001315 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001316 main.cleanup()
1317 main.exit()
1318
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001320 """
andrewonlab377693f2014-10-21 16:00:30 -04001321 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001323 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001324 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001325 """
andrewonlabe6745342014-10-17 14:29:13 -04001326 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 if jsonFormat:
1328 cmdStr = "intents -j"
1329 handle = self.sendline( cmdStr )
1330 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1331 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001332 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 cmdStr = "intents"
1334 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001335 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001336 except TypeError:
1337 main.log.exception( self.name + ": Object not as expected" )
1338 return None
andrewonlabe6745342014-10-17 14:29:13 -04001339 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001340 main.log.error( self.name + ": EOF exception found" )
1341 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001342 main.cleanup()
1343 main.exit()
1344 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001345 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001346 main.cleanup()
1347 main.exit()
1348
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001350 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001351 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001353 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001354 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001355 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001356 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if jsonFormat:
1358 cmdStr = "flows -j"
1359 handle = self.sendline( cmdStr )
1360 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1361 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001362 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 cmdStr = "flows"
1364 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001365 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 main.log.error( self.name + ".flows() response: " +
1367 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001368 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001369 except TypeError:
1370 main.log.exception( self.name + ": Object not as expected" )
1371 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001373 main.log.error( self.name + ": EOF exception found" )
1374 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001375 main.cleanup()
1376 main.exit()
1377 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001378 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001379 main.cleanup()
1380 main.exit()
1381
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1383 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001384 """
andrewonlab87852b02014-11-19 18:44:19 -05001385 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001386 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001387 a specific point-to-point intent definition
1388 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 * dpidSrc: specify source dpid
1390 * dpidDst: specify destination dpid
1391 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001392 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001394 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001395 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001396 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001397 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001398 """
andrewonlab87852b02014-11-19 18:44:19 -05001399 try:
kelvin8ec71442015-01-15 16:57:00 -08001400 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1402 str( numIntents )
1403 if numMult:
1404 cmd += " " + str( numMult )
1405 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001406 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 if appId:
1408 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001409 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1411 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001412 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.info( handle )
1415 # Split result by newline
1416 newline = handle.split( "\r\r\n" )
1417 # Ignore the first object of list, which is empty
1418 newline = newline[ 1: ]
1419 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001420 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001421 result = result.split( ": " )
1422 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1424 main.log.info( latResult )
1425 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001426 else:
1427 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001428 except TypeError:
1429 main.log.exception( self.name + ": Object not as expected" )
1430 return None
andrewonlab87852b02014-11-19 18:44:19 -05001431 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001432 main.log.error( self.name + ": EOF exception found" )
1433 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001434 main.cleanup()
1435 main.exit()
1436 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001437 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001438 main.cleanup()
1439 main.exit()
1440
kelvin-onlabd3b64892015-01-20 13:26:24 -08001441 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001442 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001443 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001444 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001445 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001446 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001447 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001448 if jsonFormat:
1449 cmdStr = "intents-events-metrics -j"
1450 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001451 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1453 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001454 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 cmdStr = "intents-events-metrics"
1456 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001457 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001458 except TypeError:
1459 main.log.exception( self.name + ": Object not as expected" )
1460 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001461 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001462 main.log.error( self.name + ": EOF exception found" )
1463 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001464 main.cleanup()
1465 main.exit()
1466 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001467 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001468 main.cleanup()
1469 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001470
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001472 """
1473 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001474 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001475 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001476 """
andrewonlab867212a2014-10-22 20:13:38 -04001477 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 if jsonFormat:
1479 cmdStr = "topology-events-metrics -j"
1480 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001482 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1483 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001484 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001485 cmdStr = "topology-events-metrics"
1486 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001487 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001488 except TypeError:
1489 main.log.exception( self.name + ": Object not as expected" )
1490 return None
andrewonlab867212a2014-10-22 20:13:38 -04001491 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001492 main.log.error( self.name + ": EOF exception found" )
1493 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001494 main.cleanup()
1495 main.exit()
1496 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001497 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001498 main.cleanup()
1499 main.exit()
1500
kelvin8ec71442015-01-15 16:57:00 -08001501 # Wrapper functions ****************
1502 # Wrapper functions use existing driver
1503 # functions and extends their use case.
1504 # For example, we may use the output of
1505 # a normal driver function, and parse it
1506 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001507
kelvin-onlabd3b64892015-01-20 13:26:24 -08001508 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001509 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001510 Description:
1511 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001512 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001513 try:
kelvin8ec71442015-01-15 16:57:00 -08001514 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 intentsStr = self.intents()
1516 allIntentList = []
1517 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001518
kelvin8ec71442015-01-15 16:57:00 -08001519 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001520 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1521 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001522 if "onos>" in intents:
1523 continue
1524 elif "intents" in intents:
1525 continue
1526 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001527 lineList = intents.split( " " )
1528 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001529
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001531
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001533 if not intents:
1534 continue
1535 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001537
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001539
Jon Halld4d4b372015-01-28 16:02:41 -08001540 except TypeError:
1541 main.log.exception( self.name + ": Object not as expected" )
1542 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001543 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001544 main.log.error( self.name + ": EOF exception found" )
1545 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001546 main.cleanup()
1547 main.exit()
1548 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001549 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001550 main.cleanup()
1551 main.exit()
1552
shahshreya353268a2015-02-25 17:03:41 -08001553
shahshreya580840d2015-02-26 10:44:04 -08001554 def FlowAddedCount( self, id ):
shahshreya353268a2015-02-25 17:03:41 -08001555 """
1556 Determine the number of flow rules for the given device id that are
1557 in the added state
1558 """
1559 try:
1560 cmdStr = "flows any " + id + " | grep 'state=ADDED' | wc -l"
1561 handle = self.sendline( cmdStr )
1562 return handle
1563 except pexpect.EOF:
1564 main.log.error( self.name + ": EOF exception found" )
1565 main.log.error( self.name + ": " + self.handle.before )
1566 main.cleanup()
1567 main.exit()
1568 except:
1569 main.log.exception( self.name + ": Uncaught exception!" )
1570 main.cleanup()
1571 main.exit()
1572
1573
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001575 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001576 Use 'devices' function to obtain list of all devices
1577 and parse the result to obtain a list of all device
1578 id's. Returns this list. Returns empty list if no
1579 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001580 List is ordered sequentially
1581
andrewonlab3e15ead2014-10-15 14:21:34 -04001582 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001583 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001584 the ids. By obtaining the list of device ids on the fly,
1585 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001586 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001587 try:
kelvin8ec71442015-01-15 16:57:00 -08001588 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001589 devicesStr = self.devices( jsonFormat=False )
1590 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001591
kelvin-onlabd3b64892015-01-20 13:26:24 -08001592 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001593 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 return idList
kelvin8ec71442015-01-15 16:57:00 -08001595
1596 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001598 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001599 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001600 # Split list further into arguments before and after string
1601 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001602 # append to idList
1603 for arg in tempList:
1604 idList.append( arg.split( "id=" )[ 1 ] )
1605 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001606
Jon Halld4d4b372015-01-28 16:02:41 -08001607 except TypeError:
1608 main.log.exception( self.name + ": Object not as expected" )
1609 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001611 main.log.error( self.name + ": EOF exception found" )
1612 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001613 main.cleanup()
1614 main.exit()
1615 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001616 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001617 main.cleanup()
1618 main.exit()
1619
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001621 """
andrewonlab7c211572014-10-15 16:45:20 -04001622 Uses 'nodes' function to obtain list of all nodes
1623 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001624 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001625 Returns:
1626 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001627 """
andrewonlab7c211572014-10-15 16:45:20 -04001628 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 nodesStr = self.nodes()
1630 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001631
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001633 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001635
kelvin-onlabd3b64892015-01-20 13:26:24 -08001636 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001637 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001638
kelvin8ec71442015-01-15 16:57:00 -08001639 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 nodesList = nodesStr.split( "," )
1641 tempList = [ node for node in nodesList if "id=" in node ]
1642 for arg in tempList:
1643 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001644
kelvin-onlabd3b64892015-01-20 13:26:24 -08001645 return idList
kelvin8ec71442015-01-15 16:57:00 -08001646
Jon Halld4d4b372015-01-28 16:02:41 -08001647 except TypeError:
1648 main.log.exception( self.name + ": Object not as expected" )
1649 return None
andrewonlab7c211572014-10-15 16:45:20 -04001650 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001653 main.cleanup()
1654 main.exit()
1655 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001656 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001657 main.cleanup()
1658 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001659
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001661 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001662 Return the first device from the devices api whose 'id' contains 'dpid'
1663 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001664 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001665 import json
1666 try:
kelvin8ec71442015-01-15 16:57:00 -08001667 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001668 return None
1669 else:
kelvin8ec71442015-01-15 16:57:00 -08001670 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 rawDevices = self.devices()
1672 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001673 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001675 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1676 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001677 return device
1678 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001679 except TypeError:
1680 main.log.exception( self.name + ": Object not as expected" )
1681 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001683 main.log.error( self.name + ": EOF exception found" )
1684 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001685 main.cleanup()
1686 main.exit()
1687 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001688 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001689 main.cleanup()
1690 main.exit()
1691
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001693 """
1694 Checks the number of swithes & links that ONOS sees against the
1695 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001696 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001697
Jon Hall42db6dc2014-10-24 19:03:48 -04001698 Params: ip = ip used for the onos cli
1699 numoswitch = expected number of switches
1700 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001701 logLevel = level to log to. Currently accepts
1702 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001703
1704
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001706
kelvin8ec71442015-01-15 16:57:00 -08001707 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001708 main.FALSE if the numer of switches and links is incorrect,
1709 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001710 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001711 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001712 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001713 if topology == {}:
1714 return main.ERROR
1715 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001716 # Is the number of switches is what we expected
1717 devices = topology.get( 'devices', False )
1718 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001719 if devices == False or links == False:
1720 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001721 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001722 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001723 linkCheck = ( int( links ) == int( numolink ) )
1724 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001725 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001726 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001727 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001728 result = main.TRUE
1729 else:
1730 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 "The number of links and switches does not matc\
1732 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001733 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001734 output = output + "\n ONOS sees %i devices (%i expected) \
1735 and %i links (%i expected)" % (
1736 int( devices ), int( numoswitch ), int( links ),
1737 int( numolink ) )
1738 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001739 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001741 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001742 else:
kelvin8ec71442015-01-15 16:57:00 -08001743 main.log.info( output )
1744 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001745 except TypeError:
1746 main.log.exception( self.name + ": Object not as expected" )
1747 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001748 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001749 main.log.error( self.name + ": EOF exception found" )
1750 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001751 main.cleanup()
1752 main.exit()
1753 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001754 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001755 main.cleanup()
1756 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001757
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001759 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001760 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 deviceId must be the id of a device as seen in the onos devices command
1762 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001763 role must be either master, standby, or none
1764
Jon Halle3f39ff2015-01-13 11:50:53 -08001765 Returns:
1766 main.TRUE or main.FALSE based on argument verification and
1767 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001768 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001769 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001770 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001771 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001772 cmdStr = "device-role " +\
1773 str( deviceId ) + " " +\
1774 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001775 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001777 if re.search( "Error", handle ):
1778 # end color output to escape any colours
1779 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001780 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001781 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001782 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001783 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001784 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001785 main.log.error( "Invalid 'role' given to device_role(). " +
1786 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001787 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001788 except TypeError:
1789 main.log.exception( self.name + ": Object not as expected" )
1790 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001792 main.log.error( self.name + ": EOF exception found" )
1793 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001794 main.cleanup()
1795 main.exit()
1796 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001797 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001798 main.cleanup()
1799 main.exit()
1800
kelvin-onlabd3b64892015-01-20 13:26:24 -08001801 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001802 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001803 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001804 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001805 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001806 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001807 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001808 if jsonFormat:
1809 cmdStr = "clusters -j"
1810 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001811 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001812 handle variable here contains some ANSI escape color code
1813 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001814 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001815 function. The repr( handle ) output when printed shows the ANSI
1816 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 variable is actually repr( somestring ) and json.loads would
1818 fail with the escape sequence. So we take off that escape
1819 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001820
kelvin-onlabd3b64892015-01-20 13:26:24 -08001821 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1822 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001823 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001824 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1825 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001826 return handle1
1827 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 cmdStr = "clusters"
1829 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001830 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001831 except TypeError:
1832 main.log.exception( self.name + ": Object not as expected" )
1833 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001835 main.log.error( self.name + ": EOF exception found" )
1836 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001837 main.cleanup()
1838 main.exit()
1839 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001840 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001841 main.cleanup()
1842 main.exit()
1843
kelvin-onlabd3b64892015-01-20 13:26:24 -08001844 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001845 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 CLI command to get the current leader for the Election test application
1847 NOTE: Requires installation of the onos-app-election feature
1848 Returns: Node IP of the leader if one exists
1849 None if none exists
1850 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001851 """
Jon Hall94fd0472014-12-08 11:52:42 -08001852 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001853 cmdStr = "election-test-leader"
1854 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 # Leader
1856 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001857 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 nodeSearch = re.search( leaderPattern, response )
1859 if nodeSearch:
1860 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001861 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001862 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001863 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 # no leader
1865 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001866 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 nullSearch = re.search( nullPattern, response )
1868 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001869 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001870 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001871 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001873 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001874 if re.search( errorPattern, response ):
1875 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001876 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001877 return main.FALSE
1878 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001879 main.log.error( "Error in election_test_leader: " +
1880 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001881 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001882 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001883 except TypeError:
1884 main.log.exception( self.name + ": Object not as expected" )
1885 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001886 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001887 main.log.error( self.name + ": EOF exception found" )
1888 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001889 main.cleanup()
1890 main.exit()
1891 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001892 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001893 main.cleanup()
1894 main.exit()
1895
kelvin-onlabd3b64892015-01-20 13:26:24 -08001896 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001897 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001898 CLI command to run for leadership of the Election test application.
1899 NOTE: Requires installation of the onos-app-election feature
1900 Returns: Main.TRUE on success
1901 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001902 """
Jon Hall94fd0472014-12-08 11:52:42 -08001903 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001904 cmdStr = "election-test-run"
1905 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001906 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001907 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001908 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001909 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001910 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001911 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001912 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001913 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001914 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001915 errorPattern = "Command\snot\sfound"
1916 if re.search( errorPattern, response ):
1917 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001918 return main.FALSE
1919 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001921 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001922 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001923 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001924 except TypeError:
1925 main.log.exception( self.name + ": Object not as expected" )
1926 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001927 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001928 main.log.error( self.name + ": EOF exception found" )
1929 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001930 main.cleanup()
1931 main.exit()
1932 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001933 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001934 main.cleanup()
1935 main.exit()
1936
kelvin-onlabd3b64892015-01-20 13:26:24 -08001937 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001938 """
Jon Hall94fd0472014-12-08 11:52:42 -08001939 * CLI command to withdraw the local node from leadership election for
1940 * the Election test application.
1941 #NOTE: Requires installation of the onos-app-election feature
1942 Returns: Main.TRUE on success
1943 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001944 """
Jon Hall94fd0472014-12-08 11:52:42 -08001945 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001946 cmdStr = "election-test-withdraw"
1947 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001948 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001949 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001950 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001951 if re.search( successPattern, response ):
1952 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001953 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001954 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001955 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001956 errorPattern = "Command\snot\sfound"
1957 if re.search( errorPattern, response ):
1958 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001959 return main.FALSE
1960 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001961 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001962 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001963 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001964 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001965 except TypeError:
1966 main.log.exception( self.name + ": Object not as expected" )
1967 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001969 main.log.error( self.name + ": EOF exception found" )
1970 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001971 main.cleanup()
1972 main.exit()
1973 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001974 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001975 main.cleanup()
1976 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001977
kelvin8ec71442015-01-15 16:57:00 -08001978 def getDevicePortsEnabledCount( self, dpid ):
1979 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001980 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001981 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001982 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001983 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1985 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001986 if re.search( "No such device", output ):
1987 main.log.error( "Error in getting ports" )
1988 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001989 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001990 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001991 except TypeError:
1992 main.log.exception( self.name + ": Object not as expected" )
1993 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001995 main.log.error( self.name + ": EOF exception found" )
1996 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001997 main.cleanup()
1998 main.exit()
1999 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002000 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002001 main.cleanup()
2002 main.exit()
2003
kelvin8ec71442015-01-15 16:57:00 -08002004 def getDeviceLinksActiveCount( self, dpid ):
2005 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002006 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002007 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002008 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002009 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2011 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002012 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002013 main.log.error( "Error in getting ports " )
2014 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002015 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002016 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002017 except TypeError:
2018 main.log.exception( self.name + ": Object not as expected" )
2019 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002021 main.log.error( self.name + ": EOF exception found" )
2022 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002023 main.cleanup()
2024 main.exit()
2025 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002026 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002027 main.cleanup()
2028 main.exit()
2029
kelvin8ec71442015-01-15 16:57:00 -08002030 def getAllIntentIds( self ):
2031 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002032 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002033 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002034 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 cmdStr = "onos:intents | grep id="
2036 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002037 if re.search( "Error", output ):
2038 main.log.error( "Error in getting ports" )
2039 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002040 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002041 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002042 except TypeError:
2043 main.log.exception( self.name + ": Object not as expected" )
2044 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002045 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002046 main.log.error( self.name + ": EOF exception found" )
2047 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002048 main.cleanup()
2049 main.exit()
2050 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002051 main.log.exception( self.name + ": Uncaught exception!" )
2052 main.cleanup()
2053 main.exit()
2054
Jon Hall3f45d112015-02-24 16:42:56 -08002055 def intentSummary( self ):
Jon Halld4d4b372015-01-28 16:02:41 -08002056 """
Jon Hall3f45d112015-02-24 16:42:56 -08002057 Returns a dictonary containing the current intent states and the count
Jon Halld4d4b372015-01-28 16:02:41 -08002058 """
Jon Halld4d4b372015-01-28 16:02:41 -08002059 try:
Jon Hall3f45d112015-02-24 16:42:56 -08002060 intents = self.intents( )
2061 intentStates = []
2062 out = []
2063 for intent in json.loads( intents ):
2064 intentStates.append( intent.get( 'state', None ) )
2065 for i in set( intentStates ):
2066 out.append( (i, intentStates.count( i ) ) )
2067 return dict( out )
Jon Halld4d4b372015-01-28 16:02:41 -08002068 except TypeError:
2069 main.log.exception( self.name + ": Object not as expected" )
2070 return None
2071 except pexpect.EOF:
2072 main.log.error( self.name + ": EOF exception found" )
2073 main.log.error( self.name + ": " + self.handle.before )
2074 main.cleanup()
2075 main.exit()
2076 except:
2077 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002078 main.cleanup()
2079 main.exit()