blob: 48f516dd9f5d6b25fe9c36199a3c96f558e83cfa [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
kelvin8ec71442015-01-15 16:57:00 -080022sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040023from drivers.common.clidriver import CLI
24
andrewonlab95ce8322014-10-13 14:12:04 -040025
kelvin8ec71442015-01-15 16:57:00 -080026class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028 def __init__( self ):
29 """
30 Initialize client
31 """
32 super( CLI, self ).__init__()
33
34 def connect( self, **connectargs ):
35 """
andrewonlab95ce8322014-10-13 14:12:04 -040036 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080037 """
andrewonlab95ce8322014-10-13 14:12:04 -040038 try:
39 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080040 vars( self )[ key ] = connectargs[ key ]
andrewonlab95ce8322014-10-13 14:12:04 -040041 self.home = "~/ONOS"
42 for key in self.options:
43 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080044 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040045 break
46
kelvin8ec71442015-01-15 16:57:00 -080047 self.name = self.options[ 'name' ]
48 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080049 user_name=self.user_name,
50 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080051 port=self.port,
52 pwd=self.pwd,
53 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040054
kelvin8ec71442015-01-15 16:57:00 -080055 self.handle.sendline( "cd " + self.home )
56 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040057 if self.handle:
58 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080059 else:
60 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040061 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080062 except TypeError:
63 main.log.exception( self.name + ": Object not as expected" )
64 return None
andrewonlab95ce8322014-10-13 14:12:04 -040065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080066 main.log.error( self.name + ": EOF exception found" )
67 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040068 main.cleanup()
69 main.exit()
70 except:
Jon Halld4d4b372015-01-28 16:02:41 -080071 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040072 main.cleanup()
73 main.exit()
74
kelvin8ec71442015-01-15 16:57:00 -080075 def disconnect( self ):
76 """
andrewonlab95ce8322014-10-13 14:12:04 -040077 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080078 """
Jon Halld61331b2015-02-17 16:35:47 -080079 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040080 try:
kelvin8ec71442015-01-15 16:57:00 -080081 self.handle.sendline( "" )
82 i = self.handle.expect( [ "onos>", "\$" ] )
Jon Hall7e5b9172014-10-22 12:32:47 -040083 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -080084 self.handle.sendline( "system:shutdown" )
85 self.handle.expect( "Confirm" )
86 self.handle.sendline( "yes" )
87 self.handle.expect( "\$" )
88 self.handle.sendline( "" )
89 self.handle.expect( "\$" )
90 self.handle.sendline( "exit" )
91 self.handle.expect( "closed" )
andrewonlabc2d05aa2014-10-13 16:51:10 -040092
Jon Halld4d4b372015-01-28 16:02:41 -080093 except TypeError:
94 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080095 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040096 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080097 main.log.error( self.name + ": EOF exception found" )
98 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040099 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800100 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400101 response = main.FALSE
102 return response
103
kelvin8ec71442015-01-15 16:57:00 -0800104 def logout( self ):
105 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500106 Sends 'logout' command to ONOS cli
kelvin8ec71442015-01-15 16:57:00 -0800107 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500108 try:
kelvin8ec71442015-01-15 16:57:00 -0800109 self.handle.sendline( "" )
110 i = self.handle.expect( [
andrewonlab9627f432014-11-14 12:45:10 -0500111 "onos>",
kelvin8ec71442015-01-15 16:57:00 -0800112 "\$" ], timeout=10 )
andrewonlab9627f432014-11-14 12:45:10 -0500113 if i == 0:
kelvin8ec71442015-01-15 16:57:00 -0800114 self.handle.sendline( "logout" )
115 self.handle.expect( "\$" )
andrewonlab9627f432014-11-14 12:45:10 -0500116 elif i == 1:
117 return main.TRUE
kelvin8ec71442015-01-15 16:57:00 -0800118
Jon Halld4d4b372015-01-28 16:02:41 -0800119 except TypeError:
120 main.log.exception( self.name + ": Object not as expected" )
121 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500122 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800123 main.log.error( self.name + ": eof exception found" )
124 main.log.error( self.name + ": " +
125 self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500126 main.cleanup()
127 main.exit()
128 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800129 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500130 main.cleanup()
131 main.exit()
132
kelvin-onlabd3b64892015-01-20 13:26:24 -0800133 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800134 """
andrewonlab95ce8322014-10-13 14:12:04 -0400135 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800136
andrewonlab95ce8322014-10-13 14:12:04 -0400137 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800138 """
andrewonlab95ce8322014-10-13 14:12:04 -0400139 try:
140 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800141 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400142 main.cleanup()
143 main.exit()
144 else:
kelvin8ec71442015-01-15 16:57:00 -0800145 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800146 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800147 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400148 # and that this driver will have to change accordingly
kelvin8ec71442015-01-15 16:57:00 -0800149 self.handle.expect( "ONOS_CELL=" + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800150 handleBefore = self.handle.before
151 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800152 # Get the rest of the handle
153 self.handle.sendline( "" )
154 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800155 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400156
kelvin-onlabd3b64892015-01-20 13:26:24 -0800157 main.log.info( "Cell call returned: " + handleBefore +
158 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400159
160 return main.TRUE
161
Jon Halld4d4b372015-01-28 16:02:41 -0800162 except TypeError:
163 main.log.exception( self.name + ": Object not as expected" )
164 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800166 main.log.error( self.name + ": eof exception found" )
167 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400168 main.cleanup()
169 main.exit()
170 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800171 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400172 main.cleanup()
173 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800174
kelvin-onlabd3b64892015-01-20 13:26:24 -0800175 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800176 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800177 karafTimeout is an optional arugument. karafTimeout value passed
178 by user would be used to set the current karaf shell idle timeout.
179 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800180 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800181 Below is an example to start a session with 60 seconds idle timeout
182 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800183
Hari Krishna25d42f72015-01-05 15:08:28 -0800184 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800185 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800186
kelvin-onlabd3b64892015-01-20 13:26:24 -0800187 Note: karafTimeout is left as str so that this could be read
188 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800189 """
andrewonlab95ce8322014-10-13 14:12:04 -0400190 try:
kelvin8ec71442015-01-15 16:57:00 -0800191 self.handle.sendline( "" )
192 x = self.handle.expect( [
193 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500194
195 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800196 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500197 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400198
kelvin8ec71442015-01-15 16:57:00 -0800199 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800200 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800201 i = self.handle.expect( [
202 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800203 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400204
205 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800207 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800208 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800209 "config:property-set -p org.apache.karaf.shell\
210 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800211 karafTimeout )
212 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800213 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800214 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400215 return main.TRUE
216 else:
kelvin8ec71442015-01-15 16:57:00 -0800217 # If failed, send ctrl+c to process and try again
218 main.log.info( "Starting CLI failed. Retrying..." )
219 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800221 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
222 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400223 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800225 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800226 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 "config:property-set -p org.apache.karaf.shell\
229 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800230 karafTimeout )
231 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800232 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800233 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400234 return main.TRUE
235 else:
kelvin8ec71442015-01-15 16:57:00 -0800236 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400238 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400239
Jon Halld4d4b372015-01-28 16:02:41 -0800240 except TypeError:
241 main.log.exception( self.name + ": Object not as expected" )
242 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400243 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800244 main.log.error( self.name + ": EOF exception found" )
245 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400246 main.cleanup()
247 main.exit()
248 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800249 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400250 main.cleanup()
251 main.exit()
252
kelvin-onlabd3b64892015-01-20 13:26:24 -0800253 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800254 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800255 Send a completely user specified string to
256 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400257 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800258
andrewonlaba18f6bf2014-10-13 19:31:54 -0400259 Warning: There are no sanity checking to commands
260 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800261 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400262 try:
kelvin8ec71442015-01-15 16:57:00 -0800263 self.handle.sendline( "" )
264 self.handle.expect( "onos>" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400265
kelvin-onlab898a6c62015-01-16 14:13:53 -0800266 self.handle.sendline( "log:log \"Sending CLI command: '"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 + cmdStr + "'\"" )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800268 self.handle.expect( "onos>" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 self.handle.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -0800270 self.handle.expect( "onos>" )
Jon Hallaea67aa2015-01-23 13:30:57 -0800271 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
272 + self.name + "." )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400273
274 handle = self.handle.before
Jon Hall7bdfc122015-01-23 11:45:32 -0800275 # Remove control strings from output
276 ansiEscape = re.compile( r'\x1b[^m]*m' )
277 handle = ansiEscape.sub( '', handle )
Jon Hall44225f82015-01-23 13:45:14 -0800278 #Remove extra return chars that get added
Jon Hallaea67aa2015-01-23 13:30:57 -0800279 handle = re.sub( r"\s\r", "", handle )
280 handle = handle.strip()
Jon Hall7bdfc122015-01-23 11:45:32 -0800281 # parse for just the output, remove the cmd from handle
282 output = handle.split( cmdStr, 1 )[1]
kelvin8ec71442015-01-15 16:57:00 -0800283
andrewonlaba18f6bf2014-10-13 19:31:54 -0400284
Jon Hall7bdfc122015-01-23 11:45:32 -0800285 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800286 except TypeError:
287 main.log.exception( self.name + ": Object not as expected" )
288 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400289 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800290 main.log.error( self.name + ": EOF exception found" )
291 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400292 main.cleanup()
293 main.exit()
294 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800295 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400296 main.cleanup()
297 main.exit()
298
kelvin8ec71442015-01-15 16:57:00 -0800299 # IMPORTANT NOTE:
300 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800301 # the cli command changing 'a:b' with 'aB'.
302 # Ex ) onos:topology > onosTopology
303 # onos:links > onosLinks
304 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800305
kelvin-onlabd3b64892015-01-20 13:26:24 -0800306 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800307 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400308 Adds a new cluster node by ID and address information.
309 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800310 * nodeId
311 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400312 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800314 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400315 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800316 cmdStr = "add-node " + str( nodeId ) + " " +\
317 str( ONOSIp ) + " " + str( tcpPort )
318 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800319 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800320 main.log.error( "Error in adding node" )
321 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800322 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400323 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400325 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800326 except TypeError:
327 main.log.exception( self.name + ": Object not as expected" )
328 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800330 main.log.error( self.name + ": EOF exception found" )
331 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400332 main.cleanup()
333 main.exit()
334 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400336 main.cleanup()
337 main.exit()
338
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800340 """
andrewonlab86dc3082014-10-13 18:18:38 -0400341 Removes a cluster by ID
342 Issues command: 'remove-node [<node-id>]'
343 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800344 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800345 """
andrewonlab86dc3082014-10-13 18:18:38 -0400346 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400347
kelvin-onlabd3b64892015-01-20 13:26:24 -0800348 cmdStr = "remove-node " + str( nodeId )
349 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800350 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400351
352 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800353
Jon Halld4d4b372015-01-28 16:02:41 -0800354 except TypeError:
355 main.log.exception( self.name + ": Object not as expected" )
356 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400357 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800358 main.log.error( self.name + ": EOF exception found" )
359 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400360 main.cleanup()
361 main.exit()
362 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800363 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400364 main.cleanup()
365 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400366
kelvin8ec71442015-01-15 16:57:00 -0800367 def nodes( self ):
368 """
andrewonlab7c211572014-10-15 16:45:20 -0400369 List the nodes currently visible
370 Issues command: 'nodes'
371 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800372 """
andrewonlab7c211572014-10-15 16:45:20 -0400373 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800374 cmdStr = "nodes"
375 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400376 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800377 except TypeError:
378 main.log.exception( self.name + ": Object not as expected" )
379 return None
andrewonlab7c211572014-10-15 16:45:20 -0400380 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800381 main.log.error( self.name + ": EOF exception found" )
382 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400383 main.cleanup()
384 main.exit()
385 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800386 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400387 main.cleanup()
388 main.exit()
389
kelvin8ec71442015-01-15 16:57:00 -0800390 def topology( self ):
391 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400392 Shows the current state of the topology
393 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800394 """
andrewonlab95ce8322014-10-13 14:12:04 -0400395 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800396 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800397 cmdStr = "onos:topology"
398 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800399 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400400 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800401 except TypeError:
402 main.log.exception( self.name + ": Object not as expected" )
403 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400404 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800405 main.log.error( self.name + ": EOF exception found" )
406 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400407 main.cleanup()
408 main.exit()
409 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800410 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400411 main.cleanup()
412 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800413
kelvin-onlabd3b64892015-01-20 13:26:24 -0800414 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800415 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800416 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400419 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800420 cmdStr = "feature:install " + str( featureStr )
421 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800422 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400423 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800424 except TypeError:
425 main.log.exception( self.name + ": Object not as expected" )
426 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400427 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800428 main.log.error( self.name + ": EOF exception found" )
429 main.log.error( self.name + ": " + self.handle.before )
430 main.log.report( "Failed to install feature" )
431 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400432 main.cleanup()
433 main.exit()
434 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800435 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800436 main.log.report( "Failed to install feature" )
437 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400438 main.cleanup()
439 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800440
kelvin-onlabd3b64892015-01-20 13:26:24 -0800441 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800442 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400443 Uninstalls a specified feature
444 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800445 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400446 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800447 cmdStr = "feature:uninstall " + str( featureStr )
448 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800449 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400450 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800451 except TypeError:
452 main.log.exception( self.name + ": Object not as expected" )
453 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800455 main.log.error( self.name + ": EOF exception found" )
456 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457 main.cleanup()
458 main.exit()
459 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800460 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400461 main.cleanup()
462 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800463
kelvin-onlabd3b64892015-01-20 13:26:24 -0800464 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800465 """
Jon Hall7b02d952014-10-17 20:14:54 -0400466 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400467 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800468 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800469 """
andrewonlab86dc3082014-10-13 18:18:38 -0400470 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800471 if jsonFormat:
472 cmdStr = "devices -j"
473 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800474 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800475 handle variable here contains some ANSI escape color code
476 sequences at the end which are invisible in the print command
477 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800478 function. The repr( handle ) output when printed shows the
479 ANSI escape sequences. In json.loads( somestring ), this
480 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800481 json.loads would fail with the escape sequence. So we take off
482 that escape sequence using:
483
kelvin-onlabd3b64892015-01-20 13:26:24 -0800484 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
485 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800486 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800487 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
488 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400489 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400490 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800491 cmdStr = "devices"
492 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400493 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800494 except TypeError:
495 main.log.exception( self.name + ": Object not as expected" )
496 return None
andrewonlab7c211572014-10-15 16:45:20 -0400497 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800498 main.log.error( self.name + ": EOF exception found" )
499 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400500 main.cleanup()
501 main.exit()
502 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800503 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400504 main.cleanup()
505 main.exit()
506
kelvin-onlabd3b64892015-01-20 13:26:24 -0800507 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800508 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800509 This balances the devices across all controllers
510 by issuing command: 'onos> onos:balance-masters'
511 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800512 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800513 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800514 cmdStr = "onos:balance-masters"
515 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800516 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800517 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800518 except TypeError:
519 main.log.exception( self.name + ": Object not as expected" )
520 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800522 main.log.error( self.name + ": EOF exception found" )
523 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800524 main.cleanup()
525 main.exit()
526 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800527 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800528 main.cleanup()
529 main.exit()
530
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800532 """
Jon Halle8217482014-10-17 13:49:14 -0400533 Lists all core links
534 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800535 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800536 """
Jon Halle8217482014-10-17 13:49:14 -0400537 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800538 if jsonFormat:
539 cmdStr = "links -j"
540 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800541 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800542 handle variable here contains some ANSI escape color code
543 sequences at the end which are invisible in the print command
544 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800545 function. The repr( handle ) output when printed shows the ANSI
546 escape sequences. In json.loads( somestring ), this somestring
547 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800548 fail with the escape sequence. So we take off that escape
549 sequence using:
550
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
552 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800553 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800554 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
555 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400556 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400557 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 cmdStr = "links"
559 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400560 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800561 except TypeError:
562 main.log.exception( self.name + ": Object not as expected" )
563 return None
Jon Halle8217482014-10-17 13:49:14 -0400564 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800565 main.log.error( self.name + ": EOF exception found" )
566 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400567 main.cleanup()
568 main.exit()
569 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800570 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400571 main.cleanup()
572 main.exit()
573
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800575 """
Jon Halle8217482014-10-17 13:49:14 -0400576 Lists all ports
577 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800579 """
Jon Halle8217482014-10-17 13:49:14 -0400580 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 if jsonFormat:
582 cmdStr = "ports -j"
583 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800584 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800585 handle variable here contains some ANSI escape color code
586 sequences at the end which are invisible in the print command
587 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800588 function. The repr( handle ) output when printed shows the ANSI
589 escape sequences. In json.loads( somestring ), this somestring
590 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800591 fail with the escape sequence. So we take off that escape
592 sequence using the following commads:
593
kelvin-onlabd3b64892015-01-20 13:26:24 -0800594 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
595 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800596 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800597 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
598 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400599 return handle1
600
Jon Halle8217482014-10-17 13:49:14 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 cmdStr = "ports"
603 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800604 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800605 except TypeError:
606 main.log.exception( self.name + ": Object not as expected" )
607 return None
Jon Halle8217482014-10-17 13:49:14 -0400608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800609 main.log.error( self.name + ": EOF exception found" )
610 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400611 main.cleanup()
612 main.exit()
613 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800614 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400615 main.cleanup()
616 main.exit()
617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
Jon Hall983a1702014-10-28 18:44:22 -0400620 Lists all devices and the controllers with roles assigned to them
621 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlab7c211572014-10-15 16:45:20 -0400624 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800625 if jsonFormat:
626 cmdStr = "roles -j"
627 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800628 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800629 handle variable here contains some ANSI escape color code
630 sequences at the end which are invisible in the print command
631 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800632 function. The repr( handle ) output when printed shows the ANSI
633 escape sequences. In json.loads( somestring ), this somestring
634 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800635 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500636
Jon Halle3f39ff2015-01-13 11:50:53 -0800637 So we take off that escape sequence using the following
638 commads:
639
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
641 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800642 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
644 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400645 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400646
andrewonlab7c211572014-10-15 16:45:20 -0400647 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 cmdStr = "roles"
649 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800650 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800651 except TypeError:
652 main.log.exception( self.name + ": Object not as expected" )
653 return None
Jon Hall983a1702014-10-28 18:44:22 -0400654 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800655 main.log.error( self.name + ": EOF exception found" )
656 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400657 main.cleanup()
658 main.exit()
659 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800660 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400661 main.cleanup()
662 main.exit()
663
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800665 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800666 Given the a string containing the json representation of the "roles"
667 cli command and a partial or whole device id, returns a json object
668 containing the roles output for the first device whose id contains
669 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400670
671 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800672 A dict of the role assignments for the given device or
673 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800674 """
Jon Hall983a1702014-10-28 18:44:22 -0400675 try:
676 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800677 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400678 return None
679 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 rawRoles = self.roles()
681 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800682 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800683 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800684 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800685 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400686 return device
687 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800688 except TypeError:
689 main.log.exception( self.name + ": Object not as expected" )
690 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400691 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800692 main.log.error( self.name + ": EOF exception found" )
693 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400694 main.cleanup()
695 main.exit()
696 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800697 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400698 main.cleanup()
699 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800700
kelvin-onlabd3b64892015-01-20 13:26:24 -0800701 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800702 """
Jon Hall94fd0472014-12-08 11:52:42 -0800703 Iterates through each device and checks if there is a master assigned
704 Returns: main.TRUE if each device has a master
705 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800706 """
Jon Hall94fd0472014-12-08 11:52:42 -0800707 try:
708 import json
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 rawRoles = self.roles()
710 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800711 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800713 # print device
714 if device[ 'master' ] == "none":
715 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800716 return main.FALSE
717 return main.TRUE
718
Jon Halld4d4b372015-01-28 16:02:41 -0800719 except TypeError:
720 main.log.exception( self.name + ": Object not as expected" )
721 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800725 main.cleanup()
726 main.exit()
727 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800728 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800729 main.cleanup()
730 main.exit()
731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800733 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400734 Returns string of paths, and the cost.
735 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800736 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400737 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
739 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800740 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800741 main.log.error( "Error in getting paths" )
742 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400743 else:
kelvin8ec71442015-01-15 16:57:00 -0800744 path = handle.split( ";" )[ 0 ]
745 cost = handle.split( ";" )[ 1 ]
746 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800747 except TypeError:
748 main.log.exception( self.name + ": Object not as expected" )
749 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800751 main.log.error( self.name + ": EOF exception found" )
752 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400753 main.cleanup()
754 main.exit()
755 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400757 main.cleanup()
758 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800759
kelvin-onlabd3b64892015-01-20 13:26:24 -0800760 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
Jon Hallffb386d2014-11-21 13:43:38 -0800762 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400763 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400766 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 if jsonFormat:
768 cmdStr = "hosts -j"
769 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800770 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800771 handle variable here contains some ANSI escape color code
772 sequences at the end which are invisible in the print command
773 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800774 function. The repr( handle ) output when printed shows the ANSI
775 escape sequences. In json.loads( somestring ), this somestring
776 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800777 fail with the escape sequence. So we take off that escape
778 sequence using:
779
kelvin-onlabd3b64892015-01-20 13:26:24 -0800780 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
781 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800782 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
784 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400785 return handle1
786 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800787 cmdStr = "hosts"
788 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400789 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800790 except TypeError:
791 main.log.exception( self.name + ": Object not as expected" )
792 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400793 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800794 main.log.error( self.name + ": EOF exception found" )
795 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400796 main.cleanup()
797 main.exit()
798 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800799 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400800 main.cleanup()
801 main.exit()
802
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800804 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400805 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800806
807 Note: mac must be a colon seperated mac address, but could be a
808 partial mac address
809
Jon Hall42db6dc2014-10-24 19:03:48 -0400810 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800811 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400812 import json
813 try:
kelvin8ec71442015-01-15 16:57:00 -0800814 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400815 return None
816 else:
817 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800818 rawHosts = self.hosts()
819 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800820 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800821 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800822 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800823 if not host:
824 pass
825 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400826 return host
827 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800828 except TypeError:
829 main.log.exception( self.name + ": Object not as expected" )
830 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400834 main.cleanup()
835 main.exit()
836 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800837 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400838 main.cleanup()
839 main.exit()
840
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800842 """
843 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400844 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800845
andrewonlab3f0a4af2014-10-17 12:25:14 -0400846 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800847 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400848 IMPORTANT:
849 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800850 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400851 Furthermore, it assumes that value of VLAN is '-1'
852 Description:
kelvin8ec71442015-01-15 16:57:00 -0800853 Converts mininet hosts ( h1, h2, h3... ) into
854 ONOS format ( 00:00:00:00:00:01/-1 , ... )
855 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400856 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800857 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400858
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800860 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800861 hostHex = hex( int( host ) ).zfill( 12 )
862 hostHex = str( hostHex ).replace( 'x', '0' )
863 i = iter( str( hostHex ) )
864 hostHex = ":".join( a + b for a, b in zip( i, i ) )
865 hostHex = hostHex + "/-1"
866 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400867
kelvin-onlabd3b64892015-01-20 13:26:24 -0800868 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400869
Jon Halld4d4b372015-01-28 16:02:41 -0800870 except TypeError:
871 main.log.exception( self.name + ": Object not as expected" )
872 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800874 main.log.error( self.name + ": EOF exception found" )
875 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400876 main.cleanup()
877 main.exit()
878 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800879 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400880 main.cleanup()
881 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400882
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800884 """
andrewonlabe6745342014-10-17 14:29:13 -0400885 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800886 * hostIdOne: ONOS host id for host1
887 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400888 Description:
kelvin8ec71442015-01-15 16:57:00 -0800889 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500890 specifying the two hosts.
kelvin8ec71442015-01-15 16:57:00 -0800891 """
andrewonlabe6745342014-10-17 14:29:13 -0400892 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 cmdStr = "add-host-intent " + str( hostIdOne ) +\
894 " " + str( hostIdTwo )
895 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800896 if re.search( "Error", handle ):
897 main.log.error( "Error in adding Host intent" )
898 return handle
899 else:
900 main.log.info( "Host intent installed between " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800902 return main.TRUE
903
Jon Halld4d4b372015-01-28 16:02:41 -0800904 except TypeError:
905 main.log.exception( self.name + ": Object not as expected" )
906 return None
andrewonlabe6745342014-10-17 14:29:13 -0400907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400910 main.cleanup()
911 main.exit()
912 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800913 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400914 main.cleanup()
915 main.exit()
916
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800918 """
andrewonlab7b31d232014-10-24 13:31:47 -0400919 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 * ingressDevice: device id of ingress device
921 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400922 Optional:
923 TODO: Still needs to be implemented via dev side
kelvin-onlab898a6c62015-01-16 14:13:53 -0800924 """
andrewonlab7b31d232014-10-24 13:31:47 -0400925 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800926 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
927 " " + str( egressDevice )
928 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800929 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800930 if re.search( "Error", handle ):
andrewonlab7b31d232014-10-24 13:31:47 -0400931 return handle
932 else:
933 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800934 except TypeError:
935 main.log.exception( self.name + ": Object not as expected" )
936 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400937 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800938 main.log.error( self.name + ": EOF exception found" )
939 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400940 main.cleanup()
941 main.exit()
942 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800943 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400944 main.cleanup()
945 main.exit()
946
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -0800948 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 ingressDevice,
950 egressDevice,
951 portIngress="",
952 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 ethType="",
954 ethSrc="",
955 ethDst="",
956 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -0800957 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800958 ipProto="",
959 ipSrc="",
960 ipDst="",
961 tcpSrc="",
962 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -0800963 """
andrewonlab4dbb4d82014-10-17 18:22:31 -0400964 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 * ingressDevice: device id of ingress device
966 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -0400967 Optional:
968 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -0800969 * ethSrc: specify ethSrc ( i.e. src mac addr )
970 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500971 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -0500973 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -0800974 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -0500975 * ipSrc: specify ip source address
976 * ipDst: specify ip destination address
977 * tcpSrc: specify tcp source port
978 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -0400979 Description:
kelvin8ec71442015-01-15 16:57:00 -0800980 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -0400981 specifying device id's and optional fields
982
Jon Halle3f39ff2015-01-13 11:50:53 -0800983 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -0400984 options developers provide for point-to-point
985 intent via cli
kelvin8ec71442015-01-15 16:57:00 -0800986 """
andrewonlab4dbb4d82014-10-17 18:22:31 -0400987 try:
andrewonlab289e4b72014-10-21 21:24:18 -0400988 cmd = ""
989
kelvin8ec71442015-01-15 16:57:00 -0800990 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -0500991 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -0500993 and not ipProto and not ipSrc and not ipDst \
994 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -0500995 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -0500996
andrewonlab289e4b72014-10-21 21:24:18 -0400997 else:
andrewonlab36af3822014-11-18 17:48:18 -0500998 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -0800999
andrewonlab0c0a6772014-10-22 12:31:18 -04001000 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001001 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001002 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001003 cmd += " --ethSrc " + str( ethSrc )
1004 if ethDst:
1005 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001006 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001007 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001009 cmd += " --lambda "
1010 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001011 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001012 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001013 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001014 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001015 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001016 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001017 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001018 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001019 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001020
kelvin8ec71442015-01-15 16:57:00 -08001021 # Check whether the user appended the port
1022 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 if "/" in ingressDevice:
1024 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001025 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 if not portIngress:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( "You must specify " +
1028 "the ingress port" )
1029 # TODO: perhaps more meaningful return
andrewonlab36af3822014-11-18 17:48:18 -05001030 return main.FALSE
1031
kelvin8ec71442015-01-15 16:57:00 -08001032 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 str( ingressDevice ) + "/" +\
1034 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001035
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 if "/" in egressDevice:
1037 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001038 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.error( "You must specify " +
1041 "the egress port" )
andrewonlab36af3822014-11-18 17:48:18 -05001042 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001043
kelvin8ec71442015-01-15 16:57:00 -08001044 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 str( egressDevice ) + "/" +\
1046 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001047
kelvin-onlab898a6c62015-01-16 14:13:53 -08001048 handle = self.sendline( cmd )
1049 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001050 main.log.error( "Error in adding point-to-point intent" )
Jon Hall47a93fb2015-01-06 16:46:06 -08001051 return main.FALSE
andrewonlab4dbb4d82014-10-17 18:22:31 -04001052 else:
1053 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001054 except TypeError:
1055 main.log.exception( self.name + ": Object not as expected" )
1056 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001057 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001058 main.log.error( self.name + ": EOF exception found" )
1059 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001060 main.cleanup()
1061 main.exit()
1062 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001063 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001064 main.cleanup()
1065 main.exit()
1066
kelvin-onlabd3b64892015-01-20 13:26:24 -08001067 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001068 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 ingressDevice1,
1070 ingressDevice2,
1071 egressDevice,
1072 portIngress="",
1073 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001074 ethType="",
1075 ethSrc="",
1076 ethDst="",
1077 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001079 ipProto="",
1080 ipSrc="",
1081 ipDst="",
1082 tcpSrc="",
1083 tcpDst="",
1084 setEthSrc="",
1085 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001086 """
shahshreyad0c80432014-12-04 16:56:05 -08001087 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001088 This function assumes that there would be 2 ingress devices and
1089 one egress device. For more number of ingress devices, this
1090 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001091 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 * ingressDevice1: device id of ingress device1
1093 * ingressDevice2: device id of ingress device2
1094 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001095 Optional:
1096 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001097 * ethSrc: specify ethSrc ( i.e. src mac addr )
1098 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001099 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001101 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001102 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001103 * ipSrc: specify ip source address
1104 * ipDst: specify ip destination address
1105 * tcpSrc: specify tcp source port
1106 * tcpDst: specify tcp destination port
1107 * setEthSrc: action to Rewrite Source MAC Address
1108 * setEthDst: action to Rewrite Destination MAC Address
1109 Description:
kelvin8ec71442015-01-15 16:57:00 -08001110 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001111 specifying device id's and optional fields
1112
Jon Halle3f39ff2015-01-13 11:50:53 -08001113 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001114 options developers provide for multipointpoint-to-singlepoint
1115 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001116 """
shahshreyad0c80432014-12-04 16:56:05 -08001117 try:
1118 cmd = ""
1119
kelvin8ec71442015-01-15 16:57:00 -08001120 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001121 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001123 and not ipProto and not ipSrc and not ipDst\
1124 and not tcpSrc and not tcpDst and not setEthSrc\
1125 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001126 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001127
1128 else:
1129 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001130
shahshreyad0c80432014-12-04 16:56:05 -08001131 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001132 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001133 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001134 cmd += " --ethSrc " + str( ethSrc )
1135 if ethDst:
1136 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001137 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001138 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001140 cmd += " --lambda "
1141 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001142 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001143 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001144 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001145 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001146 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001147 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001148 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001149 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001150 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001151 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001152 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001153 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001154 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001155
kelvin8ec71442015-01-15 16:57:00 -08001156 # Check whether the user appended the port
1157 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 if "/" in ingressDevice1:
1159 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001160 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001162 main.log.error( "You must specify " +
1163 "the ingress port1" )
1164 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001165 return main.FALSE
1166
kelvin8ec71442015-01-15 16:57:00 -08001167 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 str( ingressDevice1 ) + "/" +\
1169 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001170
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 if "/" in ingressDevice2:
1172 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001173 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001175 main.log.error( "You must specify " +
1176 "the ingress port2" )
1177 # TODO: perhaps more meaningful return
shahshreyad0c80432014-12-04 16:56:05 -08001178 return main.FALSE
1179
kelvin8ec71442015-01-15 16:57:00 -08001180 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 str( ingressDevice2 ) + "/" +\
1182 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001183
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 if "/" in egressDevice:
1185 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001186 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001188 main.log.error( "You must specify " +
1189 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001190 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001191
kelvin8ec71442015-01-15 16:57:00 -08001192 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001193 str( egressDevice ) + "/" +\
1194 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001195 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001196 handle = self.sendline( cmd )
1197 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001198 main.log.error( "Error in adding point-to-point intent" )
shahshreyad0c80432014-12-04 16:56:05 -08001199 return self.handle
1200 else:
1201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001202 except TypeError:
1203 main.log.exception( self.name + ": Object not as expected" )
1204 return None
shahshreyad0c80432014-12-04 16:56:05 -08001205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001206 main.log.error( self.name + ": EOF exception found" )
1207 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001208 main.cleanup()
1209 main.exit()
1210 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001211 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001212 main.cleanup()
1213 main.exit()
1214
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 def removeIntent( self, intentId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001216 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001217 Remove intent for specified intent id
Jon Halle3f39ff2015-01-13 11:50:53 -08001218
1219 Returns:
1220 main.False on error and
1221 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001223 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 cmdStr = "remove-intent " + str( intentId )
1225 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001226 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001227 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001228 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001229 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 # TODO: Should this be main.TRUE
1231 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001232 except TypeError:
1233 main.log.exception( self.name + ": Object not as expected" )
1234 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001235 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001236 main.log.error( self.name + ": EOF exception found" )
1237 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001238 main.cleanup()
1239 main.exit()
1240 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001241 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001242 main.cleanup()
1243 main.exit()
1244
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001246 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001247 NOTE: This method should be used after installing application:
1248 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001249 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001251 Description:
1252 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001253 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001254 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001255 if jsonFormat:
1256 cmdStr = "routes -j"
1257 handleTmp = self.sendline( cmdStr )
1258 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1259 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001260 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 cmdStr = "routes"
1262 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001263 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001264 except TypeError:
1265 main.log.exception( self.name + ": Object not as expected" )
1266 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001268 main.log.error( self.name + ": EOF exception found" )
1269 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001270 main.cleanup()
1271 main.exit()
1272 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001273 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001274 main.cleanup()
1275 main.exit()
1276
kelvin-onlabd3b64892015-01-20 13:26:24 -08001277 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001278 """
andrewonlab377693f2014-10-21 16:00:30 -04001279 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001281 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001282 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001283 """
andrewonlabe6745342014-10-17 14:29:13 -04001284 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001285 if jsonFormat:
1286 cmdStr = "intents -j"
1287 handle = self.sendline( cmdStr )
1288 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1289 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001290 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 cmdStr = "intents"
1292 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001293 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001294 except TypeError:
1295 main.log.exception( self.name + ": Object not as expected" )
1296 return None
andrewonlabe6745342014-10-17 14:29:13 -04001297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001298 main.log.error( self.name + ": EOF exception found" )
1299 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001300 main.cleanup()
1301 main.exit()
1302 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001304 main.cleanup()
1305 main.exit()
1306
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001308 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001309 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001311 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001312 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001313 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001314 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001315 if jsonFormat:
1316 cmdStr = "flows -j"
1317 handle = self.sendline( cmdStr )
1318 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1319 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001320 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001321 cmdStr = "flows"
1322 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001323 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001324 main.log.error( self.name + ".flows() response: " +
1325 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001326 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001327 except TypeError:
1328 main.log.exception( self.name + ": Object not as expected" )
1329 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001331 main.log.error( self.name + ": EOF exception found" )
1332 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001333 main.cleanup()
1334 main.exit()
1335 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001336 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001337 main.cleanup()
1338 main.exit()
1339
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1341 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001342 """
andrewonlab87852b02014-11-19 18:44:19 -05001343 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001344 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001345 a specific point-to-point intent definition
1346 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001347 * dpidSrc: specify source dpid
1348 * dpidDst: specify destination dpid
1349 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001350 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001352 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001353 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001354 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001355 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001356 """
andrewonlab87852b02014-11-19 18:44:19 -05001357 try:
kelvin8ec71442015-01-15 16:57:00 -08001358 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1360 str( numIntents )
1361 if numMult:
1362 cmd += " " + str( numMult )
1363 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001364 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 if appId:
1366 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001367 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1369 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001370 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001372 main.log.info( handle )
1373 # Split result by newline
1374 newline = handle.split( "\r\r\n" )
1375 # Ignore the first object of list, which is empty
1376 newline = newline[ 1: ]
1377 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001378 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001379 result = result.split( ": " )
1380 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1382 main.log.info( latResult )
1383 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001384 else:
1385 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001386 except TypeError:
1387 main.log.exception( self.name + ": Object not as expected" )
1388 return None
andrewonlab87852b02014-11-19 18:44:19 -05001389 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001392 main.cleanup()
1393 main.exit()
1394 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001395 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001396 main.cleanup()
1397 main.exit()
1398
kelvin-onlabd3b64892015-01-20 13:26:24 -08001399 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001400 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001401 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001402 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001404 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001405 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001406 if jsonFormat:
1407 cmdStr = "intents-events-metrics -j"
1408 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001409 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1411 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001412 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001413 cmdStr = "intents-events-metrics"
1414 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001415 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001416 except TypeError:
1417 main.log.exception( self.name + ": Object not as expected" )
1418 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001419 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001420 main.log.error( self.name + ": EOF exception found" )
1421 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001422 main.cleanup()
1423 main.exit()
1424 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001425 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001426 main.cleanup()
1427 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001428
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001430 """
1431 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001432 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001434 """
andrewonlab867212a2014-10-22 20:13:38 -04001435 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 if jsonFormat:
1437 cmdStr = "topology-events-metrics -j"
1438 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001439 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001440 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1441 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001442 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 cmdStr = "topology-events-metrics"
1444 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001445 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001446 except TypeError:
1447 main.log.exception( self.name + ": Object not as expected" )
1448 return None
andrewonlab867212a2014-10-22 20:13:38 -04001449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001450 main.log.error( self.name + ": EOF exception found" )
1451 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001452 main.cleanup()
1453 main.exit()
1454 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001455 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001456 main.cleanup()
1457 main.exit()
1458
kelvin8ec71442015-01-15 16:57:00 -08001459 # Wrapper functions ****************
1460 # Wrapper functions use existing driver
1461 # functions and extends their use case.
1462 # For example, we may use the output of
1463 # a normal driver function, and parse it
1464 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001465
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001467 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001468 Description:
1469 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001470 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001471 try:
kelvin8ec71442015-01-15 16:57:00 -08001472 # Obtain output of intents function
kelvin-onlabd3b64892015-01-20 13:26:24 -08001473 intentsStr = self.intents()
1474 allIntentList = []
1475 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001476
kelvin8ec71442015-01-15 16:57:00 -08001477 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1479 for intents in intentsList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001480 if "onos>" in intents:
1481 continue
1482 elif "intents" in intents:
1483 continue
1484 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001485 lineList = intents.split( " " )
1486 allIntentList.append( lineList[ 0 ] )
kelvin8ec71442015-01-15 16:57:00 -08001487
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 allIntentList = allIntentList[ 1:-2 ]
andrewonlab9a50dfe2014-10-17 17:22:31 -04001489
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 for intents in allIntentList:
andrewonlab9a50dfe2014-10-17 17:22:31 -04001491 if not intents:
1492 continue
1493 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 intentIdList.append( intents )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001495
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001497
Jon Halld4d4b372015-01-28 16:02:41 -08001498 except TypeError:
1499 main.log.exception( self.name + ": Object not as expected" )
1500 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001501 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001502 main.log.error( self.name + ": EOF exception found" )
1503 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001504 main.cleanup()
1505 main.exit()
1506 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001507 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001508 main.cleanup()
1509 main.exit()
1510
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001512 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001513 Use 'devices' function to obtain list of all devices
1514 and parse the result to obtain a list of all device
1515 id's. Returns this list. Returns empty list if no
1516 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001517 List is ordered sequentially
1518
andrewonlab3e15ead2014-10-15 14:21:34 -04001519 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001520 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001521 the ids. By obtaining the list of device ids on the fly,
1522 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001523 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001524 try:
kelvin8ec71442015-01-15 16:57:00 -08001525 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 devicesStr = self.devices( jsonFormat=False )
1527 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001528
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001530 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 return idList
kelvin8ec71442015-01-15 16:57:00 -08001532
1533 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001534 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001535 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001537 # Split list further into arguments before and after string
1538 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001539 # append to idList
1540 for arg in tempList:
1541 idList.append( arg.split( "id=" )[ 1 ] )
1542 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001543
Jon Halld4d4b372015-01-28 16:02:41 -08001544 except TypeError:
1545 main.log.exception( self.name + ": Object not as expected" )
1546 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001547 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001548 main.log.error( self.name + ": EOF exception found" )
1549 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001550 main.cleanup()
1551 main.exit()
1552 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001553 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001554 main.cleanup()
1555 main.exit()
1556
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001558 """
andrewonlab7c211572014-10-15 16:45:20 -04001559 Uses 'nodes' function to obtain list of all nodes
1560 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001561 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001562 Returns:
1563 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001564 """
andrewonlab7c211572014-10-15 16:45:20 -04001565 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 nodesStr = self.nodes()
1567 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001568
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001570 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001572
kelvin-onlabd3b64892015-01-20 13:26:24 -08001573 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001574 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001575
kelvin8ec71442015-01-15 16:57:00 -08001576 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 nodesList = nodesStr.split( "," )
1578 tempList = [ node for node in nodesList if "id=" in node ]
1579 for arg in tempList:
1580 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001581
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 return idList
kelvin8ec71442015-01-15 16:57:00 -08001583
Jon Halld4d4b372015-01-28 16:02:41 -08001584 except TypeError:
1585 main.log.exception( self.name + ": Object not as expected" )
1586 return None
andrewonlab7c211572014-10-15 16:45:20 -04001587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001588 main.log.error( self.name + ": EOF exception found" )
1589 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001590 main.cleanup()
1591 main.exit()
1592 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001593 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001594 main.cleanup()
1595 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001596
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001598 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001599 Return the first device from the devices api whose 'id' contains 'dpid'
1600 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001601 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001602 import json
1603 try:
kelvin8ec71442015-01-15 16:57:00 -08001604 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001605 return None
1606 else:
kelvin8ec71442015-01-15 16:57:00 -08001607 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001608 rawDevices = self.devices()
1609 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001610 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001612 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1613 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001614 return device
1615 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001616 except TypeError:
1617 main.log.exception( self.name + ": Object not as expected" )
1618 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001619 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001620 main.log.error( self.name + ": EOF exception found" )
1621 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001622 main.cleanup()
1623 main.exit()
1624 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001625 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001626 main.cleanup()
1627 main.exit()
1628
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001630 """
1631 Checks the number of swithes & links that ONOS sees against the
1632 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001633 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001634
Jon Hall42db6dc2014-10-24 19:03:48 -04001635 Params: ip = ip used for the onos cli
1636 numoswitch = expected number of switches
1637 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001638 logLevel = level to log to. Currently accepts
1639 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001640
1641
kelvin-onlabd3b64892015-01-20 13:26:24 -08001642 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001643
kelvin8ec71442015-01-15 16:57:00 -08001644 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001645 main.FALSE if the numer of switches and links is incorrect,
1646 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001647 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001648 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001649 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001650 if topology == {}:
1651 return main.ERROR
1652 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001653 # Is the number of switches is what we expected
1654 devices = topology.get( 'devices', False )
1655 links = topology.get( 'links', False )
Jon Hall42db6dc2014-10-24 19:03:48 -04001656 if devices == False or links == False:
1657 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001658 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001659 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001660 linkCheck = ( int( links ) == int( numolink ) )
1661 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001662 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001663 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001664 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001665 result = main.TRUE
1666 else:
1667 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 "The number of links and switches does not matc\
1669 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001670 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001671 output = output + "\n ONOS sees %i devices (%i expected) \
1672 and %i links (%i expected)" % (
1673 int( devices ), int( numoswitch ), int( links ),
1674 int( numolink ) )
1675 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001676 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001677 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001678 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001679 else:
kelvin8ec71442015-01-15 16:57:00 -08001680 main.log.info( output )
1681 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001682 except TypeError:
1683 main.log.exception( self.name + ": Object not as expected" )
1684 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001685 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( self.name + ": EOF exception found" )
1687 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001688 main.cleanup()
1689 main.exit()
1690 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001691 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001692 main.cleanup()
1693 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001694
kelvin-onlabd3b64892015-01-20 13:26:24 -08001695 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001696 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001697 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001698 deviceId must be the id of a device as seen in the onos devices command
1699 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001700 role must be either master, standby, or none
1701
Jon Halle3f39ff2015-01-13 11:50:53 -08001702 Returns:
1703 main.TRUE or main.FALSE based on argument verification and
1704 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001705 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001706 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001707 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001708 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001709 cmdStr = "device-role " +\
1710 str( deviceId ) + " " +\
1711 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001712 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001713 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001714 if re.search( "Error", handle ):
1715 # end color output to escape any colours
1716 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001717 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001718 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001719 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001720 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001721 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001722 main.log.error( "Invalid 'role' given to device_role(). " +
1723 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001724 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001725 except TypeError:
1726 main.log.exception( self.name + ": Object not as expected" )
1727 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001728 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001729 main.log.error( self.name + ": EOF exception found" )
1730 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001731 main.cleanup()
1732 main.exit()
1733 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001734 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001735 main.cleanup()
1736 main.exit()
1737
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001739 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001740 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001741 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001742 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001743 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001744 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001745 if jsonFormat:
1746 cmdStr = "clusters -j"
1747 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001748 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001749 handle variable here contains some ANSI escape color code
1750 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001751 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001752 function. The repr( handle ) output when printed shows the ANSI
1753 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001754 variable is actually repr( somestring ) and json.loads would
1755 fail with the escape sequence. So we take off that escape
1756 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001757
kelvin-onlabd3b64892015-01-20 13:26:24 -08001758 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1759 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001760 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001761 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1762 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001763 return handle1
1764 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001765 cmdStr = "clusters"
1766 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001767 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001768 except TypeError:
1769 main.log.exception( self.name + ": Object not as expected" )
1770 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001772 main.log.error( self.name + ": EOF exception found" )
1773 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001774 main.cleanup()
1775 main.exit()
1776 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001777 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001778 main.cleanup()
1779 main.exit()
1780
kelvin-onlabd3b64892015-01-20 13:26:24 -08001781 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001782 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001783 CLI command to get the current leader for the Election test application
1784 NOTE: Requires installation of the onos-app-election feature
1785 Returns: Node IP of the leader if one exists
1786 None if none exists
1787 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001788 """
Jon Hall94fd0472014-12-08 11:52:42 -08001789 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001790 cmdStr = "election-test-leader"
1791 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001792 # Leader
1793 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001794 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 nodeSearch = re.search( leaderPattern, response )
1796 if nodeSearch:
1797 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001798 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001799 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001800 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001801 # no leader
1802 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001803 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001804 nullSearch = re.search( nullPattern, response )
1805 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001806 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001807 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001808 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001809 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001810 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001811 if re.search( errorPattern, response ):
1812 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001813 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001814 return main.FALSE
1815 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001816 main.log.error( "Error in election_test_leader: " +
1817 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001818 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001819 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001820 except TypeError:
1821 main.log.exception( self.name + ": Object not as expected" )
1822 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001823 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001824 main.log.error( self.name + ": EOF exception found" )
1825 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001826 main.cleanup()
1827 main.exit()
1828 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001829 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001830 main.cleanup()
1831 main.exit()
1832
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001834 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001835 CLI command to run for leadership of the Election test application.
1836 NOTE: Requires installation of the onos-app-election feature
1837 Returns: Main.TRUE on success
1838 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001839 """
Jon Hall94fd0472014-12-08 11:52:42 -08001840 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001841 cmdStr = "election-test-run"
1842 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001843 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001844 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001845 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08001847 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08001848 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001850 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001851 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001852 errorPattern = "Command\snot\sfound"
1853 if re.search( errorPattern, response ):
1854 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001855 return main.FALSE
1856 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001858 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001859 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001860 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001861 except TypeError:
1862 main.log.exception( self.name + ": Object not as expected" )
1863 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001864 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001865 main.log.error( self.name + ": EOF exception found" )
1866 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001867 main.cleanup()
1868 main.exit()
1869 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001870 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001871 main.cleanup()
1872 main.exit()
1873
kelvin-onlabd3b64892015-01-20 13:26:24 -08001874 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08001875 """
Jon Hall94fd0472014-12-08 11:52:42 -08001876 * CLI command to withdraw the local node from leadership election for
1877 * the Election test application.
1878 #NOTE: Requires installation of the onos-app-election feature
1879 Returns: Main.TRUE on success
1880 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08001881 """
Jon Hall94fd0472014-12-08 11:52:42 -08001882 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001883 cmdStr = "election-test-withdraw"
1884 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001885 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08001886 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001887 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08001888 if re.search( successPattern, response ):
1889 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001890 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08001891 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08001892 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001893 errorPattern = "Command\snot\sfound"
1894 if re.search( errorPattern, response ):
1895 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08001896 return main.FALSE
1897 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001898 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001899 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001900 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001901 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001902 except TypeError:
1903 main.log.exception( self.name + ": Object not as expected" )
1904 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001906 main.log.error( self.name + ": EOF exception found" )
1907 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001908 main.cleanup()
1909 main.exit()
1910 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001911 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001912 main.cleanup()
1913 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001914
kelvin8ec71442015-01-15 16:57:00 -08001915 def getDevicePortsEnabledCount( self, dpid ):
1916 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001917 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001918 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001919 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001921 cmdStr = "onos:ports -e " + dpid + " | wc -l"
1922 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001923 if re.search( "No such device", output ):
1924 main.log.error( "Error in getting ports" )
1925 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001926 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001927 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001928 except TypeError:
1929 main.log.exception( self.name + ": Object not as expected" )
1930 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001931 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001932 main.log.error( self.name + ": EOF exception found" )
1933 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001934 main.cleanup()
1935 main.exit()
1936 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001937 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001938 main.cleanup()
1939 main.exit()
1940
kelvin8ec71442015-01-15 16:57:00 -08001941 def getDeviceLinksActiveCount( self, dpid ):
1942 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001943 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08001944 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001945 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001946 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
1948 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001949 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001950 main.log.error( "Error in getting ports " )
1951 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001952 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001953 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001957 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001960 main.cleanup()
1961 main.exit()
1962 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001963 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001964 main.cleanup()
1965 main.exit()
1966
kelvin8ec71442015-01-15 16:57:00 -08001967 def getAllIntentIds( self ):
1968 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001969 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08001970 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001971 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001972 cmdStr = "onos:intents | grep id="
1973 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001974 if re.search( "Error", output ):
1975 main.log.error( "Error in getting ports" )
1976 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001977 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001978 return output
Jon Halld4d4b372015-01-28 16:02:41 -08001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08001985 main.cleanup()
1986 main.exit()
1987 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001988 main.log.exception( self.name + ": Uncaught exception!" )
1989 main.cleanup()
1990 main.exit()
1991
1992 def testExceptions( self, obj ):
1993 """
1994 Test exception logging
1995 """
1996 # FIXME: Remove this before you commit
1997
1998 try:
1999 return obj[ 'dedf' ]
2000 except TypeError:
2001 main.log.exception( self.name + ": Object not as expected" )
2002 return None
2003 except pexpect.EOF:
2004 main.log.error( self.name + ": EOF exception found" )
2005 main.log.error( self.name + ": " + self.handle.before )
2006 main.cleanup()
2007 main.exit()
2008 except:
2009 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002010 main.cleanup()
2011 main.exit()