blob: d6702c7b3c229d43eb31e1bb234e4d4998d0d776 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
andrewonlab95ce8322014-10-13 14:12:04 -04004This driver enters the onos> prompt to issue commands.
5
kelvin8ec71442015-01-15 16:57:00 -08006Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -04007functions and document properly.
8
9If you are a contributor to the driver, please
10list your email here for future contact:
11
12jhall@onlab.us
13andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040014shreya@onlab.us
andrewonlab95ce8322014-10-13 14:12:04 -040015
16OCT 13 2014
17
kelvin8ec71442015-01-15 16:57:00 -080018"""
andrewonlab95ce8322014-10-13 14:12:04 -040019import sys
andrewonlab95ce8322014-10-13 14:12:04 -040020import pexpect
21import re
Jon Hall30b82fa2015-03-04 17:15:43 -080022import json
23import types
kelvin8ec71442015-01-15 16:57:00 -080024sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
34 super( CLI, self ).__init__()
35
36 def connect( self, **connectargs ):
37 """
andrewonlab95ce8322014-10-13 14:12:04 -040038 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080039 """
andrewonlab95ce8322014-10-13 14:12:04 -040040 try:
41 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080042 vars( self )[ key ] = connectargs[ key ]
andrewonlab95ce8322014-10-13 14:12:04 -040043 self.home = "~/ONOS"
44 for key in self.options:
45 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080046 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040047 break
kelvin-onlabfb521662015-02-27 09:52:40 -080048 if self.home is None or self.home == "":
kelvin-onlabd6634ac2015-01-29 14:23:10 -080049 self.home = "~/ONOS"
kelvin-onlabfb521662015-02-27 09:52:40 -080050
kelvin8ec71442015-01-15 16:57:00 -080051 self.name = self.options[ 'name' ]
52 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080053 user_name=self.user_name,
54 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080055 port=self.port,
56 pwd=self.pwd,
57 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040058
kelvin8ec71442015-01-15 16:57:00 -080059 self.handle.sendline( "cd " + self.home )
60 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040061 if self.handle:
62 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080063 else:
64 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040065 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080066 except TypeError:
67 main.log.exception( self.name + ": Object not as expected" )
68 return None
andrewonlab95ce8322014-10-13 14:12:04 -040069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080070 main.log.error( self.name + ": EOF exception found" )
71 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040072 main.cleanup()
73 main.exit()
74 except:
Jon Halld4d4b372015-01-28 16:02:41 -080075 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -040076 main.cleanup()
77 main.exit()
78
kelvin8ec71442015-01-15 16:57:00 -080079 def disconnect( self ):
80 """
andrewonlab95ce8322014-10-13 14:12:04 -040081 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -080082 """
Jon Halld61331b2015-02-17 16:35:47 -080083 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -040084 try:
Jon Hallb7fce3e2015-03-04 10:18:32 -080085 self.logout()
kelvin8ec71442015-01-15 16:57:00 -080086 self.handle.sendline( "" )
87 self.handle.expect( "\$" )
88 self.handle.sendline( "exit" )
89 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -080092 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 except:
Jon Halld4d4b372015-01-28 16:02:41 -080097 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -040098 response = main.FALSE
99 return response
100
kelvin8ec71442015-01-15 16:57:00 -0800101 def logout( self ):
102 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500103 Sends 'logout' command to ONOS cli
kelvin8ec71442015-01-15 16:57:00 -0800104 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500105 try:
kelvin8ec71442015-01-15 16:57:00 -0800106 self.handle.sendline( "" )
Jon Hallb7fce3e2015-03-04 10:18:32 -0800107 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
108 timeout=10 )
109 if i == 0: # In ONOS CLI
kelvin8ec71442015-01-15 16:57:00 -0800110 self.handle.sendline( "logout" )
111 self.handle.expect( "\$" )
Jon Hallb7fce3e2015-03-04 10:18:32 -0800112 elif i == 1: # not in CLI
andrewonlab9627f432014-11-14 12:45:10 -0500113 return main.TRUE
Jon Hallb7fce3e2015-03-04 10:18:32 -0800114 elif i == 3: # Timeout
115 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
118 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": eof exception found" )
121 main.log.error( self.name + ": " +
122 self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500123 main.cleanup()
124 main.exit()
125 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500127 main.cleanup()
128 main.exit()
129
kelvin-onlabd3b64892015-01-20 13:26:24 -0800130 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800131 """
andrewonlab95ce8322014-10-13 14:12:04 -0400132 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800133
andrewonlab95ce8322014-10-13 14:12:04 -0400134 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800135 """
andrewonlab95ce8322014-10-13 14:12:04 -0400136 try:
137 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800138 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400139 main.cleanup()
140 main.exit()
141 else:
kelvin8ec71442015-01-15 16:57:00 -0800142 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800143 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800144 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400145 # and that this driver will have to change accordingly
Jon Hall1e03cb62015-02-19 12:07:12 -0800146 self.handle.expect( "ONOS_CELL" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800147 handleBefore = self.handle.before
148 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800149 # Get the rest of the handle
150 self.handle.sendline( "" )
151 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800152 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400153
kelvin-onlabd3b64892015-01-20 13:26:24 -0800154 main.log.info( "Cell call returned: " + handleBefore +
155 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400156
157 return main.TRUE
158
Jon Halld4d4b372015-01-28 16:02:41 -0800159 except TypeError:
160 main.log.exception( self.name + ": Object not as expected" )
161 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400162 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800163 main.log.error( self.name + ": eof exception found" )
164 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400165 main.cleanup()
166 main.exit()
167 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800168 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400169 main.cleanup()
170 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800171
kelvin-onlabd3b64892015-01-20 13:26:24 -0800172 def startOnosCli( self, ONOSIp, karafTimeout="" ):
kelvin8ec71442015-01-15 16:57:00 -0800173 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800174 karafTimeout is an optional arugument. karafTimeout value passed
175 by user would be used to set the current karaf shell idle timeout.
176 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800177 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800178 Below is an example to start a session with 60 seconds idle timeout
179 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800180
Hari Krishna25d42f72015-01-05 15:08:28 -0800181 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800183
kelvin-onlabd3b64892015-01-20 13:26:24 -0800184 Note: karafTimeout is left as str so that this could be read
185 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800186 """
andrewonlab95ce8322014-10-13 14:12:04 -0400187 try:
kelvin8ec71442015-01-15 16:57:00 -0800188 self.handle.sendline( "" )
189 x = self.handle.expect( [
190 "\$", "onos>" ], timeout=10 )
andrewonlab48829f62014-11-17 13:49:01 -0500191
192 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800193 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500194 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400195
kelvin8ec71442015-01-15 16:57:00 -0800196 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800197 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800198 i = self.handle.expect( [
199 "onos>",
kelvin-onlab898a6c62015-01-16 14:13:53 -0800200 pexpect.TIMEOUT ], timeout=60 )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400201
202 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800203 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800204 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800205 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800206 "config:property-set -p org.apache.karaf.shell\
207 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800208 karafTimeout )
209 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800210 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800211 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400212 return main.TRUE
213 else:
kelvin8ec71442015-01-15 16:57:00 -0800214 # If failed, send ctrl+c to process and try again
215 main.log.info( "Starting CLI failed. Retrying..." )
216 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800218 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
219 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400220 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800221 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800222 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800223 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800224 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800225 "config:property-set -p org.apache.karaf.shell\
226 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800227 karafTimeout )
228 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400231 return main.TRUE
232 else:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800234 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400235 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400236
Jon Halld4d4b372015-01-28 16:02:41 -0800237 except TypeError:
238 main.log.exception( self.name + ": Object not as expected" )
239 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400240 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800241 main.log.error( self.name + ": EOF exception found" )
242 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400243 main.cleanup()
244 main.exit()
245 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800246 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400247 main.cleanup()
248 main.exit()
249
kelvin-onlab338f5512015-02-06 10:53:16 -0800250 def log( self, cmdStr , level = "" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800251 """
252 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800253 returns main.TRUE on success
254 returns main.FALSE if Error occured
255 Available level: DEBUG, TRACE, INFO, WARN, ERROR
256 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800257 """
258 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800259 lvlStr = ""
260 if level:
261 lvlStr = "--level=" + level
262
kelvin-onlab9f541032015-02-04 16:19:53 -0800263 self.handle.sendline( "" )
264 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800265 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
kelvin-onlab9f541032015-02-04 16:19:53 -0800266 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800267
kelvin-onlab9f541032015-02-04 16:19:53 -0800268 response = self.handle.before
269 if re.search( "Error", response ):
270 return main.FALSE
271 return main.TRUE
272
273 except pexpect.EOF:
274 main.log.error( self.name + ": EOF exception found" )
275 main.log.error( self.name + ": " + self.handle.before )
276 main.cleanup()
277 main.exit()
278 except:
kelvin-onlabfb521662015-02-27 09:52:40 -0800279 main.log.exception( self.name + ": Uncaught exception!" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800280 main.cleanup()
281 main.exit()
282
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 def sendline( self, cmdStr ):
kelvin8ec71442015-01-15 16:57:00 -0800284 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800285 Send a completely user specified string to
286 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400287 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800288
andrewonlaba18f6bf2014-10-13 19:31:54 -0400289 Warning: There are no sanity checking to commands
290 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800291 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400292 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800293 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
294 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800295 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800296 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
297 response = self.handle.before
298 if i == 2:
299 self.handle.sendline()
300 self.handle.expect( "\$" )
301 response += self.handle.before
302 print response
303 try:
304 print self.handle.after
305 except:
306 pass
307 # TODO: do something with i
Jon Hallaea67aa2015-01-23 13:30:57 -0800308 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
309 + self.name + "." )
Jon Hall7bdfc122015-01-23 11:45:32 -0800310 # Remove control strings from output
311 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800312 response = ansiEscape.sub( '', response )
kelvin-onlabfb521662015-02-27 09:52:40 -0800313 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800314 response = re.sub( r"\s\r", "", response )
315 response = response.strip()
316 # parse for just the output, remove the cmd from response
317 output = response.split( cmdStr, 1 )[1]
Jon Hall7bdfc122015-01-23 11:45:32 -0800318 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800319 except TypeError:
320 main.log.exception( self.name + ": Object not as expected" )
321 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400322 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( self.name + ": EOF exception found" )
324 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400325 main.cleanup()
326 main.exit()
327 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800328 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400329 main.cleanup()
330 main.exit()
331
kelvin8ec71442015-01-15 16:57:00 -0800332 # IMPORTANT NOTE:
333 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800334 # the cli command changing 'a:b' with 'aB'.
335 # Ex ) onos:topology > onosTopology
336 # onos:links > onosLinks
337 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800338
kelvin-onlabd3b64892015-01-20 13:26:24 -0800339 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800340 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400341 Adds a new cluster node by ID and address information.
342 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800343 * nodeId
344 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400345 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800346 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800347 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400348 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800349 cmdStr = "add-node " + str( nodeId ) + " " +\
350 str( ONOSIp ) + " " + str( tcpPort )
351 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800352 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800353 main.log.error( "Error in adding node" )
354 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800355 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400356 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800357 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400358 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800359 except TypeError:
360 main.log.exception( self.name + ": Object not as expected" )
361 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400362 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800363 main.log.error( self.name + ": EOF exception found" )
364 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400365 main.cleanup()
366 main.exit()
367 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800368 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400369 main.cleanup()
370 main.exit()
371
kelvin-onlabd3b64892015-01-20 13:26:24 -0800372 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800373 """
andrewonlab86dc3082014-10-13 18:18:38 -0400374 Removes a cluster by ID
375 Issues command: 'remove-node [<node-id>]'
376 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800377 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800378 """
andrewonlab86dc3082014-10-13 18:18:38 -0400379 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400380
kelvin-onlabd3b64892015-01-20 13:26:24 -0800381 cmdStr = "remove-node " + str( nodeId )
382 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800383 # TODO: add error checking. Does ONOS give any errors?
andrewonlab86dc3082014-10-13 18:18:38 -0400384
385 return main.TRUE
Jon Halle3f39ff2015-01-13 11:50:53 -0800386
Jon Halld4d4b372015-01-28 16:02:41 -0800387 except TypeError:
388 main.log.exception( self.name + ": Object not as expected" )
389 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400393 main.cleanup()
394 main.exit()
395 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800396 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400397 main.cleanup()
398 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400399
kelvin8ec71442015-01-15 16:57:00 -0800400 def nodes( self ):
401 """
andrewonlab7c211572014-10-15 16:45:20 -0400402 List the nodes currently visible
403 Issues command: 'nodes'
404 Returns: entire handle of list of nodes
kelvin8ec71442015-01-15 16:57:00 -0800405 """
andrewonlab7c211572014-10-15 16:45:20 -0400406 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800407 cmdStr = "nodes"
408 handle = self.sendline( cmdStr )
andrewonlab7c211572014-10-15 16:45:20 -0400409 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800410 except TypeError:
411 main.log.exception( self.name + ": Object not as expected" )
412 return None
andrewonlab7c211572014-10-15 16:45:20 -0400413 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800414 main.log.error( self.name + ": EOF exception found" )
415 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400416 main.cleanup()
417 main.exit()
418 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800419 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400420 main.cleanup()
421 main.exit()
422
kelvin8ec71442015-01-15 16:57:00 -0800423 def topology( self ):
424 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400425 Shows the current state of the topology
426 by issusing command: 'onos> onos:topology'
kelvin8ec71442015-01-15 16:57:00 -0800427 """
andrewonlab95ce8322014-10-13 14:12:04 -0400428 try:
Jon Halle3f39ff2015-01-13 11:50:53 -0800429 # either onos:topology or 'topology' will work in CLI
kelvin-onlabd3b64892015-01-20 13:26:24 -0800430 cmdStr = "onos:topology"
431 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800432 main.log.info( "onos:topology returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400433 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800434 except TypeError:
435 main.log.exception( self.name + ": Object not as expected" )
436 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800438 main.log.error( self.name + ": EOF exception found" )
439 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400440 main.cleanup()
441 main.exit()
442 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800443 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400444 main.cleanup()
445 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800446
kelvin-onlabd3b64892015-01-20 13:26:24 -0800447 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800448 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800449 Installs a specified feature
andrewonlabc2d05aa2014-10-13 16:51:10 -0400450 by issuing command: 'onos> feature:install <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800451 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400452 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800453 cmdStr = "feature:install " + str( featureStr )
454 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800455 # TODO: Check for possible error responses from karaf
andrewonlabc2d05aa2014-10-13 16:51:10 -0400456 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800457 except TypeError:
458 main.log.exception( self.name + ": Object not as expected" )
459 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400460 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800461 main.log.error( self.name + ": EOF exception found" )
462 main.log.error( self.name + ": " + self.handle.before )
463 main.log.report( "Failed to install feature" )
464 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400465 main.cleanup()
466 main.exit()
467 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800468 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800469 main.log.report( "Failed to install feature" )
470 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400471 main.cleanup()
472 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800473
kelvin-onlabd3b64892015-01-20 13:26:24 -0800474 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800475 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400476 Uninstalls a specified feature
477 by issuing command: 'onos> feature:uninstall <feature_str>'
kelvin8ec71442015-01-15 16:57:00 -0800478 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800480 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
481 handle = self.sendline( cmdStr )
482 if handle != '':
483 cmdStr = "feature:uninstall " + str( featureStr )
484 self.sendline( cmdStr )
485 # TODO: Check for possible error responses from karaf
486 else:
487 main.log.info( "Feature needs to be installed before uninstalling it" )
shahshreya280223a2015-02-26 12:25:25 -0800488 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800489 except TypeError:
490 main.log.exception( self.name + ": Object not as expected" )
491 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800493 main.log.error( self.name + ": EOF exception found" )
494 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400495 main.cleanup()
496 main.exit()
497 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800498 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400499 main.cleanup()
500 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800501
kelvin-onlabd3b64892015-01-20 13:26:24 -0800502 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800503 """
Jon Hall7b02d952014-10-17 20:14:54 -0400504 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400505 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800507 """
andrewonlab86dc3082014-10-13 18:18:38 -0400508 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 if jsonFormat:
510 cmdStr = "devices -j"
511 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800512 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800513 handle variable here contains some ANSI escape color code
514 sequences at the end which are invisible in the print command
515 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800516 function. The repr( handle ) output when printed shows the
517 ANSI escape sequences. In json.loads( somestring ), this
518 somestring variable is actually repr( somestring ) and
Jon Halle3f39ff2015-01-13 11:50:53 -0800519 json.loads would fail with the escape sequence. So we take off
520 that escape sequence using:
521
kelvin-onlabd3b64892015-01-20 13:26:24 -0800522 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
523 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800524 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800525 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
526 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400527 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400528 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800529 cmdStr = "devices"
530 handle = self.sendline( cmdStr )
Jon Hallcd707292014-10-17 19:06:17 -0400531 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800532 except TypeError:
533 main.log.exception( self.name + ": Object not as expected" )
534 return None
andrewonlab7c211572014-10-15 16:45:20 -0400535 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800536 main.log.error( self.name + ": EOF exception found" )
537 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400538 main.cleanup()
539 main.exit()
540 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800541 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400542 main.cleanup()
543 main.exit()
544
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800546 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800547 This balances the devices across all controllers
548 by issuing command: 'onos> onos:balance-masters'
549 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800550 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800551 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 cmdStr = "onos:balance-masters"
553 self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800554 # TODO: Check for error responses from ONOS
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800555 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800556 except TypeError:
557 main.log.exception( self.name + ": Object not as expected" )
558 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800562 main.cleanup()
563 main.exit()
564 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800565 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800566 main.cleanup()
567 main.exit()
568
kelvin-onlabd3b64892015-01-20 13:26:24 -0800569 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800570 """
Jon Halle8217482014-10-17 13:49:14 -0400571 Lists all core links
572 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800574 """
Jon Halle8217482014-10-17 13:49:14 -0400575 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 if jsonFormat:
577 cmdStr = "links -j"
578 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800579 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800580 handle variable here contains some ANSI escape color code
581 sequences at the end which are invisible in the print command
582 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800583 function. The repr( handle ) output when printed shows the ANSI
584 escape sequences. In json.loads( somestring ), this somestring
585 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800586 fail with the escape sequence. So we take off that escape
587 sequence using:
588
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
590 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800591 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
593 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400594 return handle1
Jon Halle8217482014-10-17 13:49:14 -0400595 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 cmdStr = "links"
597 handle = self.sendline( cmdStr )
Jon Halla001c392014-10-17 18:50:59 -0400598 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800599 except TypeError:
600 main.log.exception( self.name + ": Object not as expected" )
601 return None
Jon Halle8217482014-10-17 13:49:14 -0400602 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800603 main.log.error( self.name + ": EOF exception found" )
604 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400605 main.cleanup()
606 main.exit()
607 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800608 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400609 main.cleanup()
610 main.exit()
611
kelvin-onlabd3b64892015-01-20 13:26:24 -0800612 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800613 """
Jon Halle8217482014-10-17 13:49:14 -0400614 Lists all ports
615 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800617 """
Jon Halle8217482014-10-17 13:49:14 -0400618 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800619 if jsonFormat:
620 cmdStr = "ports -j"
621 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800622 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800623 handle variable here contains some ANSI escape color code
624 sequences at the end which are invisible in the print command
625 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800626 function. The repr( handle ) output when printed shows the ANSI
627 escape sequences. In json.loads( somestring ), this somestring
628 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800629 fail with the escape sequence. So we take off that escape
630 sequence using the following commads:
631
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
633 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800634 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800635 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
636 handle1 = ansiEscape.sub( '', handle )
Jon Halla001c392014-10-17 18:50:59 -0400637 return handle1
638
Jon Halle8217482014-10-17 13:49:14 -0400639 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 cmdStr = "ports"
641 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800642 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800643 except TypeError:
644 main.log.exception( self.name + ": Object not as expected" )
645 return None
Jon Halle8217482014-10-17 13:49:14 -0400646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800647 main.log.error( self.name + ": EOF exception found" )
648 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400649 main.cleanup()
650 main.exit()
651 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800652 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400653 main.cleanup()
654 main.exit()
655
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
Jon Hall983a1702014-10-28 18:44:22 -0400658 Lists all devices and the controllers with roles assigned to them
659 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800660 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800661 """
andrewonlab7c211572014-10-15 16:45:20 -0400662 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800663 if jsonFormat:
664 cmdStr = "roles -j"
665 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800666 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800667 handle variable here contains some ANSI escape color code
668 sequences at the end which are invisible in the print command
669 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800670 function. The repr( handle ) output when printed shows the ANSI
671 escape sequences. In json.loads( somestring ), this somestring
672 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800673 fail with the escape sequence.
Jon Hallb1290e82014-11-18 16:17:48 -0500674
Jon Halle3f39ff2015-01-13 11:50:53 -0800675 So we take off that escape sequence using the following
676 commads:
677
kelvin-onlabd3b64892015-01-20 13:26:24 -0800678 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
679 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800680 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
682 handle1 = ansiEscape.sub( '', handle )
Jon Hall983a1702014-10-28 18:44:22 -0400683 return handle1
andrewonlab7c211572014-10-15 16:45:20 -0400684
andrewonlab7c211572014-10-15 16:45:20 -0400685 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 cmdStr = "roles"
687 handle = self.sendline( cmdStr )
Jon Hallffb386d2014-11-21 13:43:38 -0800688 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800689 except TypeError:
690 main.log.exception( self.name + ": Object not as expected" )
691 return None
Jon Hall983a1702014-10-28 18:44:22 -0400692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800693 main.log.error( self.name + ": EOF exception found" )
694 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400695 main.cleanup()
696 main.exit()
697 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800698 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400699 main.cleanup()
700 main.exit()
701
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800703 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800704 Given the a string containing the json representation of the "roles"
705 cli command and a partial or whole device id, returns a json object
706 containing the roles output for the first device whose id contains
707 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400708
709 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800710 A dict of the role assignments for the given device or
711 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800712 """
Jon Hall983a1702014-10-28 18:44:22 -0400713 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400715 return None
716 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800717 rawRoles = self.roles()
718 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800719 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800721 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400723 return device
724 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800725 except TypeError:
726 main.log.exception( self.name + ": Object not as expected" )
727 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400728 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800729 main.log.error( self.name + ": EOF exception found" )
730 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400731 main.cleanup()
732 main.exit()
733 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800734 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400735 main.cleanup()
736 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
Jon Hall94fd0472014-12-08 11:52:42 -0800740 Iterates through each device and checks if there is a master assigned
741 Returns: main.TRUE if each device has a master
742 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800743 """
Jon Hall94fd0472014-12-08 11:52:42 -0800744 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 rawRoles = self.roles()
746 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800747 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800748 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800749 # print device
750 if device[ 'master' ] == "none":
751 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800752 return main.FALSE
753 return main.TRUE
754
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800761 main.cleanup()
762 main.exit()
763 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800765 main.cleanup()
766 main.exit()
767
kelvin-onlabd3b64892015-01-20 13:26:24 -0800768 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800769 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400770 Returns string of paths, and the cost.
771 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800772 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
775 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800776 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800777 main.log.error( "Error in getting paths" )
778 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400779 else:
kelvin8ec71442015-01-15 16:57:00 -0800780 path = handle.split( ";" )[ 0 ]
781 cost = handle.split( ";" )[ 1 ]
782 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800783 except TypeError:
784 main.log.exception( self.name + ": Object not as expected" )
785 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400786 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800787 main.log.error( self.name + ": EOF exception found" )
788 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400789 main.cleanup()
790 main.exit()
791 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800792 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400793 main.cleanup()
794 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800795
kelvin-onlabd3b64892015-01-20 13:26:24 -0800796 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800797 """
Jon Hallffb386d2014-11-21 13:43:38 -0800798 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400799 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800801 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400802 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 if jsonFormat:
804 cmdStr = "hosts -j"
805 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800806 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800807 handle variable here contains some ANSI escape color code
808 sequences at the end which are invisible in the print command
809 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -0800810 function. The repr( handle ) output when printed shows the ANSI
811 escape sequences. In json.loads( somestring ), this somestring
812 variable is actually repr( somestring ) and json.loads would
Jon Halle3f39ff2015-01-13 11:50:53 -0800813 fail with the escape sequence. So we take off that escape
814 sequence using:
815
kelvin-onlabd3b64892015-01-20 13:26:24 -0800816 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
817 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800818 """
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
820 handle1 = ansiEscape.sub( '', handle )
Jon Hall42db6dc2014-10-24 19:03:48 -0400821 return handle1
822 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 cmdStr = "hosts"
824 handle = self.sendline( cmdStr )
Jon Hall42db6dc2014-10-24 19:03:48 -0400825 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800826 except TypeError:
827 main.log.exception( self.name + ": Object not as expected" )
828 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400829 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800830 main.log.error( self.name + ": EOF exception found" )
831 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400832 main.cleanup()
833 main.exit()
834 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800835 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400836 main.cleanup()
837 main.exit()
838
kelvin-onlabd3b64892015-01-20 13:26:24 -0800839 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800840 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400841 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800842
843 Note: mac must be a colon seperated mac address, but could be a
844 partial mac address
845
Jon Hall42db6dc2014-10-24 19:03:48 -0400846 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400848 try:
kelvin8ec71442015-01-15 16:57:00 -0800849 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400850 return None
851 else:
852 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 rawHosts = self.hosts()
854 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800855 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800857 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800858 if not host:
859 pass
860 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400861 return host
862 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800863 except TypeError:
864 main.log.exception( self.name + ": Object not as expected" )
865 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400866 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800867 main.log.error( self.name + ": EOF exception found" )
868 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400869 main.cleanup()
870 main.exit()
871 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800872 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400873 main.cleanup()
874 main.exit()
875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
878 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400879 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800880
andrewonlab3f0a4af2014-10-17 12:25:14 -0400881 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400883 IMPORTANT:
884 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800885 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400886 Furthermore, it assumes that value of VLAN is '-1'
887 Description:
kelvin8ec71442015-01-15 16:57:00 -0800888 Converts mininet hosts ( h1, h2, h3... ) into
889 ONOS format ( 00:00:00:00:00:01/-1 , ... )
890 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400891 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400893
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800895 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 hostHex = hex( int( host ) ).zfill( 12 )
897 hostHex = str( hostHex ).replace( 'x', '0' )
898 i = iter( str( hostHex ) )
899 hostHex = ":".join( a + b for a, b in zip( i, i ) )
900 hostHex = hostHex + "/-1"
901 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400902
kelvin-onlabd3b64892015-01-20 13:26:24 -0800903 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400904
Jon Halld4d4b372015-01-28 16:02:41 -0800905 except TypeError:
906 main.log.exception( self.name + ": Object not as expected" )
907 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400908 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800909 main.log.error( self.name + ": EOF exception found" )
910 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400911 main.cleanup()
912 main.exit()
913 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800914 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400915 main.cleanup()
916 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400917
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800919 """
andrewonlabe6745342014-10-17 14:29:13 -0400920 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 * hostIdOne: ONOS host id for host1
922 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400923 Description:
kelvin8ec71442015-01-15 16:57:00 -0800924 Adds a host-to-host intent ( bidrectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500925 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800926 Returns:
927 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800928 """
andrewonlabe6745342014-10-17 14:29:13 -0400929 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800930 cmdStr = "add-host-intent " + str( hostIdOne ) +\
931 " " + str( hostIdTwo )
932 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800933 if re.search( "Error", handle ):
934 main.log.error( "Error in adding Host intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800935 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800936 else:
937 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800938 str( hostIdOne ) + " and " + str( hostIdTwo ) )
939 match = re.search('id=0x([\da-f]+),', handle)
940 if match:
941 return match.group()[3:-1]
942 else:
943 main.log.error( "Error, intent ID not found" )
944 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800945 except TypeError:
946 main.log.exception( self.name + ": Object not as expected" )
947 return None
andrewonlabe6745342014-10-17 14:29:13 -0400948 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800949 main.log.error( self.name + ": EOF exception found" )
950 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400951 main.cleanup()
952 main.exit()
953 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800954 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400955 main.cleanup()
956 main.exit()
957
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800959 """
andrewonlab7b31d232014-10-24 13:31:47 -0400960 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 * ingressDevice: device id of ingress device
962 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -0400963 Optional:
964 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -0800965 Description:
966 Adds an optical intent by specifying an ingress and egress device
967 Returns:
968 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -0800969 """
andrewonlab7b31d232014-10-24 13:31:47 -0400970 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
972 " " + str( egressDevice )
973 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800974 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -0800975 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -0800976 main.log.error( "Error in adding Optical intent" )
977 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400978 else:
kelvin-onlabfb521662015-02-27 09:52:40 -0800979 main.log.info( "Optical intent installed between " +
980 str( ingressDevice ) + " and " +
981 str( egressDevice ) )
982 match = re.search('id=0x([\da-f]+),', handle)
983 if match:
984 return match.group()[3:-1]
985 else:
986 main.log.error( "Error, intent ID not found" )
987 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800988 except TypeError:
989 main.log.exception( self.name + ": Object not as expected" )
990 return None
andrewonlab7b31d232014-10-24 13:31:47 -0400991 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800992 main.log.error( self.name + ": EOF exception found" )
993 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -0400994 main.cleanup()
995 main.exit()
996 except:
Jon Halld4d4b372015-01-28 16:02:41 -0800997 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -0400998 main.cleanup()
999 main.exit()
1000
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001002 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 ingressDevice,
1004 egressDevice,
1005 portIngress="",
1006 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001007 ethType="",
1008 ethSrc="",
1009 ethDst="",
1010 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001012 ipProto="",
1013 ipSrc="",
1014 ipDst="",
1015 tcpSrc="",
1016 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001018 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 * ingressDevice: device id of ingress device
1020 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001021 Optional:
1022 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001023 * ethSrc: specify ethSrc ( i.e. src mac addr )
1024 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001025 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001027 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001028 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001029 * ipSrc: specify ip source address
1030 * ipDst: specify ip destination address
1031 * tcpSrc: specify tcp source port
1032 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001033 Description:
kelvin8ec71442015-01-15 16:57:00 -08001034 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001035 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001036 Returns:
1037 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001038
Jon Halle3f39ff2015-01-13 11:50:53 -08001039 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001040 options developers provide for point-to-point
1041 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001042 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001043 try:
andrewonlab289e4b72014-10-21 21:24:18 -04001044 cmd = ""
1045
kelvin8ec71442015-01-15 16:57:00 -08001046 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001047 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001049 and not ipProto and not ipSrc and not ipDst \
1050 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001051 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001052
andrewonlab289e4b72014-10-21 21:24:18 -04001053 else:
andrewonlab36af3822014-11-18 17:48:18 -05001054 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001055
andrewonlab0c0a6772014-10-22 12:31:18 -04001056 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001057 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001058 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001059 cmd += " --ethSrc " + str( ethSrc )
1060 if ethDst:
1061 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001062 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001063 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001065 cmd += " --lambda "
1066 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001067 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001068 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001069 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001070 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001071 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001072 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001073 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001074 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001075 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001076
kelvin8ec71442015-01-15 16:57:00 -08001077 # Check whether the user appended the port
1078 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 if "/" in ingressDevice:
1080 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001081 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001083 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001084 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001085 # Would it make sense to throw an exception and exit
1086 # the test?
1087 return None
andrewonlab36af3822014-11-18 17:48:18 -05001088
kelvin8ec71442015-01-15 16:57:00 -08001089 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 str( ingressDevice ) + "/" +\
1091 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001092
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 if "/" in egressDevice:
1094 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001095 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001097 main.log.error( "You must specify the egress port" )
1098 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001099
kelvin8ec71442015-01-15 16:57:00 -08001100 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 str( egressDevice ) + "/" +\
1102 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001103
kelvin-onlab898a6c62015-01-16 14:13:53 -08001104 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001105 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001106 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001108 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001109 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001110 # TODO: print out all the options in this message?
1111 main.log.info( "Point-to-point intent installed between " +
1112 str( ingressDevice ) + " and " +
1113 str( egressDevice ) )
1114 match = re.search('id=0x([\da-f]+),', handle)
1115 if match:
1116 return match.group()[3:-1]
1117 else:
1118 main.log.error( "Error, intent ID not found" )
1119 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001120 except TypeError:
1121 main.log.exception( self.name + ": Object not as expected" )
1122 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001126 main.cleanup()
1127 main.exit()
1128 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001129 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001130 main.cleanup()
1131 main.exit()
1132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001134 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001135 ingressDevice1,
1136 ingressDevice2,
1137 egressDevice,
kelvin-onlabfb521662015-02-27 09:52:40 -08001138 portIngress1="",
1139 portIngress2="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001141 ethType="",
1142 ethSrc="",
1143 ethDst="",
1144 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001146 ipProto="",
1147 ipSrc="",
1148 ipDst="",
1149 tcpSrc="",
1150 tcpDst="",
1151 setEthSrc="",
1152 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001153 """
shahshreyad0c80432014-12-04 16:56:05 -08001154 Note:
Jon Halle3f39ff2015-01-13 11:50:53 -08001155 This function assumes that there would be 2 ingress devices and
1156 one egress device. For more number of ingress devices, this
1157 function needs to be modified
shahshreyad0c80432014-12-04 16:56:05 -08001158 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 * ingressDevice1: device id of ingress device1
1160 * ingressDevice2: device id of ingress device2
1161 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001162 Optional:
1163 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001164 * ethSrc: specify ethSrc ( i.e. src mac addr )
1165 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001166 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001168 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001169 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001170 * ipSrc: specify ip source address
1171 * ipDst: specify ip destination address
1172 * tcpSrc: specify tcp source port
1173 * tcpDst: specify tcp destination port
1174 * setEthSrc: action to Rewrite Source MAC Address
1175 * setEthDst: action to Rewrite Destination MAC Address
1176 Description:
kelvin8ec71442015-01-15 16:57:00 -08001177 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001178 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001179 Returns:
1180 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001181
Jon Halle3f39ff2015-01-13 11:50:53 -08001182 NOTE: This function may change depending on the
shahshreyad0c80432014-12-04 16:56:05 -08001183 options developers provide for multipointpoint-to-singlepoint
1184 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001185 """
shahshreyad0c80432014-12-04 16:56:05 -08001186 try:
1187 cmd = ""
1188
kelvin8ec71442015-01-15 16:57:00 -08001189 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001190 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001192 and not ipProto and not ipSrc and not ipDst\
1193 and not tcpSrc and not tcpDst and not setEthSrc\
1194 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001195 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001196
1197 else:
1198 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001199
shahshreyad0c80432014-12-04 16:56:05 -08001200 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001201 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001202 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001203 cmd += " --ethSrc " + str( ethSrc )
1204 if ethDst:
1205 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001206 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001207 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001209 cmd += " --lambda "
1210 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001211 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001212 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001213 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001214 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001216 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001217 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001218 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001219 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001220 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001221 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001222 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001223 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001224
kelvin8ec71442015-01-15 16:57:00 -08001225 # Check whether the user appended the port
1226 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 if "/" in ingressDevice1:
1228 cmd += " " + str( ingressDevice1 )
shahshreyad0c80432014-12-04 16:56:05 -08001229 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001230 if not portIngress1:
kelvin8ec71442015-01-15 16:57:00 -08001231 main.log.error( "You must specify " +
1232 "the ingress port1" )
1233 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 return None
shahshreyad0c80432014-12-04 16:56:05 -08001235
kelvin8ec71442015-01-15 16:57:00 -08001236 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001237 str( ingressDevice1 ) + "/" +\
1238 str( portIngress1 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001239
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 if "/" in ingressDevice2:
1241 cmd += " " + str( ingressDevice2 )
shahshreyad0c80432014-12-04 16:56:05 -08001242 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 if not portIngress2:
kelvin8ec71442015-01-15 16:57:00 -08001244 main.log.error( "You must specify " +
1245 "the ingress port2" )
1246 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001247 return None
shahshreyad0c80432014-12-04 16:56:05 -08001248
kelvin8ec71442015-01-15 16:57:00 -08001249 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 str( ingressDevice2 ) + "/" +\
1251 str( portIngress2 ) + " "
shahshreyad0c80432014-12-04 16:56:05 -08001252
kelvin-onlabd3b64892015-01-20 13:26:24 -08001253 if "/" in egressDevice:
1254 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001255 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001257 main.log.error( "You must specify " +
1258 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001259 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001260
kelvin8ec71442015-01-15 16:57:00 -08001261 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001262 str( egressDevice ) + "/" +\
1263 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001264 print "cmd= ", cmd
kelvin-onlab898a6c62015-01-16 14:13:53 -08001265 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001266 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001267 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001268 main.log.error( "Error in adding multipoint-to-singlepoint " +
1269 "intent" )
1270 return None
shahshreyad0c80432014-12-04 16:56:05 -08001271 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001272 # TODO: print out all the options in this message?
1273 main.log.info( "Multipoint-to-singlepoint intent installed" +
1274 " between " + str( ingressDevice1 ) + ", " +
1275 str( ingressDevice2 ) + " and " +
1276 str( egressDevice ) )
1277 match = re.search('id=0x([\da-f]+),', handle)
1278 if match:
1279 return match.group()[3:-1]
1280 else:
1281 main.log.error( "Error, intent ID not found" )
1282 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001283 except TypeError:
1284 main.log.exception( self.name + ": Object not as expected" )
1285 return None
shahshreyad0c80432014-12-04 16:56:05 -08001286 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001289 main.cleanup()
1290 main.exit()
1291 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001292 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001293 main.cleanup()
1294 main.exit()
1295
shahshreya1c818fc2015-02-26 13:44:08 -08001296 def removeIntent( self, intentId, app = 'org.onosproject.cli',
1297 purge = False, sync = False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001298 """
shahshreya1c818fc2015-02-26 13:44:08 -08001299 Remove intent for specified application id and intent id
1300 Optional args:-
1301 -s or --sync: Waits for the removal before returning
1302 -p or --purge: Purge the intent from the store after removal
1303
Jon Halle3f39ff2015-01-13 11:50:53 -08001304 Returns:
1305 main.False on error and
1306 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001307 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001308 try:
shahshreya1c818fc2015-02-26 13:44:08 -08001309 cmdStr = "remove-intent "
1310 if purge:
1311 cmdStr += " -p"
1312 if sync:
1313 cmdStr += " -s"
1314
1315 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001316 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001317 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001318 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001319 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001320 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001321 # TODO: Should this be main.TRUE
1322 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001323 except TypeError:
1324 main.log.exception( self.name + ": Object not as expected" )
1325 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001326 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001327 main.log.error( self.name + ": EOF exception found" )
1328 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001329 main.cleanup()
1330 main.exit()
1331 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001332 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001333 main.cleanup()
1334 main.exit()
1335
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001337 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001338 NOTE: This method should be used after installing application:
1339 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001340 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001342 Description:
1343 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001344 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001345 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 if jsonFormat:
1347 cmdStr = "routes -j"
1348 handleTmp = self.sendline( cmdStr )
1349 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1350 handle = ansiEscape.sub( '', handleTmp )
pingping-lin8b306ac2014-11-17 18:13:51 -08001351 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 cmdStr = "routes"
1353 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001354 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001355 except TypeError:
1356 main.log.exception( self.name + ": Object not as expected" )
1357 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001358 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001359 main.log.error( self.name + ": EOF exception found" )
1360 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001361 main.cleanup()
1362 main.exit()
1363 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001364 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001365 main.cleanup()
1366 main.exit()
1367
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001369 """
andrewonlab377693f2014-10-21 16:00:30 -04001370 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001371 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001372 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001373 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001374 """
andrewonlabe6745342014-10-17 14:29:13 -04001375 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001376 if jsonFormat:
1377 cmdStr = "intents -j"
1378 handle = self.sendline( cmdStr )
1379 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1380 handle = ansiEscape.sub( '', handle )
kelvin8ec71442015-01-15 16:57:00 -08001381 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 cmdStr = "intents"
1383 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001384 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001385 except TypeError:
1386 main.log.exception( self.name + ": Object not as expected" )
1387 return None
andrewonlabe6745342014-10-17 14:29:13 -04001388 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001389 main.log.error( self.name + ": EOF exception found" )
1390 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001391 main.cleanup()
1392 main.exit()
1393 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001394 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001395 main.cleanup()
1396 main.exit()
1397
kelvin-onlab54400a92015-02-26 18:05:51 -08001398 def getIntentState(self, intentsId, intentsJson=None):
1399 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001400 Check intent state.
1401 Accepts a single intent ID (string type) or a list of intent IDs.
1402 Returns the state(string type) of the id if a single intent ID is
1403 accepted.
1404 Returns a dictionary with intent IDs as the key and its corresponding
1405 states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001406 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001407 intentId: intent ID (string type)
1408 intentsJson: parsed json object from the onos:intents api
1409 Returns:
1410 state = An intent's state- INSTALL,WITHDRAWN etc.
1411 stateDict = Dictionary of intent's state. intent ID as the keys and
1412 state as the values.
1413 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001414 try:
1415 state = "State is Undefined"
1416 if not intentsJson:
1417 intentsJsonTemp = json.loads(self.intents())
1418 else:
1419 intentsJsonTemp = json.loads(intentsJson)
1420 if isinstance(intentsId,types.StringType):
1421 for intent in intentsJsonTemp:
1422 if intentsId == intent['id']:
1423 state = intent['state']
1424 return state
1425 main.log.info("Cannot find intent ID" + str(intentsId) +" on the list")
1426 return state
1427 elif isinstance(intentsId,types.ListType):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001428 dictList = []
kelvin-onlab54400a92015-02-26 18:05:51 -08001429 for ID in intentsId:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001430 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001431 for intents in intentsJsonTemp:
1432 if ID == intents['id']:
kelvin-onlab07dbd012015-03-04 16:29:39 -08001433 stateDict['state'] = intents['state']
1434 stateDict['id'] = ID
1435 dictList.append(stateDict)
kelvin-onlab54400a92015-02-26 18:05:51 -08001436 break
kelvin-onlab07dbd012015-03-04 16:29:39 -08001437 if len(intentsId) != len(dictList):
kelvin-onlab54400a92015-02-26 18:05:51 -08001438 main.log.info("Cannot find some of the intent ID state")
kelvin-onlab07dbd012015-03-04 16:29:39 -08001439 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001440 else:
1441 main.log.info("Invalid intents ID entry")
1442 return None
1443 main.log.info("Something went wrong getting intent ID state")
1444 return None
1445 except TypeError:
1446 main.log.exception( self.name + ": Object not as expected" )
1447 return None
1448 except pexpect.EOF:
1449 main.log.error( self.name + ": EOF exception found" )
1450 main.log.error( self.name + ": " + self.handle.before )
1451 main.cleanup()
1452 main.exit()
1453 except:
1454 main.log.exception( self.name + ": Uncaught exception!" )
1455 main.cleanup()
1456 main.exit()
Jon Hall30b82fa2015-03-04 17:15:43 -08001457
kelvin-onlabd3b64892015-01-20 13:26:24 -08001458 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001459 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001460 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001462 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001463 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001464 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001465 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 if jsonFormat:
1467 cmdStr = "flows -j"
1468 handle = self.sendline( cmdStr )
1469 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1470 handle = ansiEscape.sub( '', handle )
Shreya Shah0f01c812014-10-26 20:15:28 -04001471 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001472 cmdStr = "flows"
1473 handle = self.sendline( cmdStr )
kelvin8ec71442015-01-15 16:57:00 -08001474 if re.search( "Error\sexecuting\scommand:", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001475 main.log.error( self.name + ".flows() response: " +
1476 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001477 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001478 except TypeError:
1479 main.log.exception( self.name + ": Object not as expected" )
1480 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001481 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001482 main.log.error( self.name + ": EOF exception found" )
1483 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001484 main.cleanup()
1485 main.exit()
1486 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001487 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001488 main.cleanup()
1489 main.exit()
1490
kelvin-onlabd3b64892015-01-20 13:26:24 -08001491 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
1492 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001493 """
andrewonlab87852b02014-11-19 18:44:19 -05001494 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001495 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001496 a specific point-to-point intent definition
1497 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 * dpidSrc: specify source dpid
1499 * dpidDst: specify destination dpid
1500 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001501 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001503 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001504 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001505 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001506 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001507 """
andrewonlab87852b02014-11-19 18:44:19 -05001508 try:
kelvin8ec71442015-01-15 16:57:00 -08001509 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1511 str( numIntents )
1512 if numMult:
1513 cmd += " " + str( numMult )
1514 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001515 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 if appId:
1517 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001518 handle = self.sendline( cmd )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1520 handle = ansiEscape.sub( '', handle )
andrewonlab87852b02014-11-19 18:44:19 -05001521 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001522 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001523 main.log.info( handle )
1524 # Split result by newline
1525 newline = handle.split( "\r\r\n" )
1526 # Ignore the first object of list, which is empty
1527 newline = newline[ 1: ]
1528 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001529 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001530 result = result.split( ": " )
1531 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001532 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1533 main.log.info( latResult )
1534 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001535 else:
1536 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001537 except TypeError:
1538 main.log.exception( self.name + ": Object not as expected" )
1539 return None
andrewonlab87852b02014-11-19 18:44:19 -05001540 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001541 main.log.error( self.name + ": EOF exception found" )
1542 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001543 main.cleanup()
1544 main.exit()
1545 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001546 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001547 main.cleanup()
1548 main.exit()
1549
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001551 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001552 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001553 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001554 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001555 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001556 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001557 if jsonFormat:
1558 cmdStr = "intents-events-metrics -j"
1559 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001560 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1562 handle = ansiEscape.sub( '', handle )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001563 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 cmdStr = "intents-events-metrics"
1565 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001566 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001567 except TypeError:
1568 main.log.exception( self.name + ": Object not as expected" )
1569 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001570 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001571 main.log.error( self.name + ": EOF exception found" )
1572 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001573 main.cleanup()
1574 main.exit()
1575 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001576 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001577 main.cleanup()
1578 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04001579
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001581 """
1582 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04001583 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001584 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001585 """
andrewonlab867212a2014-10-22 20:13:38 -04001586 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 if jsonFormat:
1588 cmdStr = "topology-events-metrics -j"
1589 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001590 # Some color thing that we want to escape
kelvin-onlabd3b64892015-01-20 13:26:24 -08001591 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1592 handle = ansiEscape.sub( '', handle )
andrewonlab867212a2014-10-22 20:13:38 -04001593 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001594 cmdStr = "topology-events-metrics"
1595 handle = self.sendline( cmdStr )
andrewonlab867212a2014-10-22 20:13:38 -04001596 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001597 except TypeError:
1598 main.log.exception( self.name + ": Object not as expected" )
1599 return None
andrewonlab867212a2014-10-22 20:13:38 -04001600 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001601 main.log.error( self.name + ": EOF exception found" )
1602 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04001603 main.cleanup()
1604 main.exit()
1605 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001606 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04001607 main.cleanup()
1608 main.exit()
1609
kelvin8ec71442015-01-15 16:57:00 -08001610 # Wrapper functions ****************
1611 # Wrapper functions use existing driver
1612 # functions and extends their use case.
1613 # For example, we may use the output of
1614 # a normal driver function, and parse it
1615 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04001616
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001618 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001619 Description:
1620 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08001621 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001622 try:
kelvin8ec71442015-01-15 16:57:00 -08001623 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08001624 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04001626
kelvin8ec71442015-01-15 16:57:00 -08001627 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08001628 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
1629 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08001630 match = re.search('id=0x([\da-f]+),', intents)
1631 if match:
1632 tmpId = match.group()[3:-1]
1633 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001634 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04001635
Jon Halld4d4b372015-01-28 16:02:41 -08001636 except TypeError:
1637 main.log.exception( self.name + ": Object not as expected" )
1638 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001639 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001640 main.log.error( self.name + ": EOF exception found" )
1641 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001642 main.cleanup()
1643 main.exit()
1644 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001645 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001646 main.cleanup()
1647 main.exit()
1648
Jon Hall30b82fa2015-03-04 17:15:43 -08001649 def FlowAddedCount( self, deviceId ):
1650 """
1651 Determine the number of flow rules for the given device id that are
1652 in the added state
1653 """
1654 try:
1655 cmdStr = "flows any " + str( deviceId ) + " | " +\
1656 "grep 'state=ADDED' | wc -l"
1657 handle = self.sendline( cmdStr )
1658 return handle
1659 except pexpect.EOF:
1660 main.log.error( self.name + ": EOF exception found" )
1661 main.log.error( self.name + ": " + self.handle.before )
1662 main.cleanup()
1663 main.exit()
1664 except:
1665 main.log.exception( self.name + ": Uncaught exception!" )
1666 main.cleanup()
1667 main.exit()
1668
kelvin-onlabd3b64892015-01-20 13:26:24 -08001669 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001670 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001671 Use 'devices' function to obtain list of all devices
1672 and parse the result to obtain a list of all device
1673 id's. Returns this list. Returns empty list if no
1674 devices exist
kelvin8ec71442015-01-15 16:57:00 -08001675 List is ordered sequentially
1676
andrewonlab3e15ead2014-10-15 14:21:34 -04001677 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08001678 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04001679 the ids. By obtaining the list of device ids on the fly,
1680 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08001681 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04001682 try:
kelvin8ec71442015-01-15 16:57:00 -08001683 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 devicesStr = self.devices( jsonFormat=False )
1685 idList = []
kelvin8ec71442015-01-15 16:57:00 -08001686
kelvin-onlabd3b64892015-01-20 13:26:24 -08001687 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08001688 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001689 return idList
kelvin8ec71442015-01-15 16:57:00 -08001690
1691 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001692 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08001693 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08001694 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08001695 # Split list further into arguments before and after string
1696 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08001697 # append to idList
1698 for arg in tempList:
1699 idList.append( arg.split( "id=" )[ 1 ] )
1700 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04001701
Jon Halld4d4b372015-01-28 16:02:41 -08001702 except TypeError:
1703 main.log.exception( self.name + ": Object not as expected" )
1704 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04001705 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001706 main.log.error( self.name + ": EOF exception found" )
1707 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001708 main.cleanup()
1709 main.exit()
1710 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001711 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001712 main.cleanup()
1713 main.exit()
1714
kelvin-onlabd3b64892015-01-20 13:26:24 -08001715 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08001716 """
andrewonlab7c211572014-10-15 16:45:20 -04001717 Uses 'nodes' function to obtain list of all nodes
1718 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08001719 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04001720 Returns:
1721 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08001722 """
andrewonlab7c211572014-10-15 16:45:20 -04001723 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 nodesStr = self.nodes()
1725 idList = []
andrewonlab7c211572014-10-15 16:45:20 -04001726
kelvin-onlabd3b64892015-01-20 13:26:24 -08001727 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08001728 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001729 return idList
andrewonlab7c211572014-10-15 16:45:20 -04001730
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 # Sample nodesStr output
kelvin8ec71442015-01-15 16:57:00 -08001732 # id=local, address=127.0.0.1:9876, state=ACTIVE *
andrewonlab7c211572014-10-15 16:45:20 -04001733
kelvin8ec71442015-01-15 16:57:00 -08001734 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08001735 nodesList = nodesStr.split( "," )
1736 tempList = [ node for node in nodesList if "id=" in node ]
1737 for arg in tempList:
1738 idList.append( arg.split( "id=" )[ 1 ] )
andrewonlab7c211572014-10-15 16:45:20 -04001739
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 return idList
kelvin8ec71442015-01-15 16:57:00 -08001741
Jon Halld4d4b372015-01-28 16:02:41 -08001742 except TypeError:
1743 main.log.exception( self.name + ": Object not as expected" )
1744 return None
andrewonlab7c211572014-10-15 16:45:20 -04001745 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001746 main.log.error( self.name + ": EOF exception found" )
1747 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04001748 main.cleanup()
1749 main.exit()
1750 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001751 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04001752 main.cleanup()
1753 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001754
kelvin-onlabd3b64892015-01-20 13:26:24 -08001755 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08001756 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001757 Return the first device from the devices api whose 'id' contains 'dpid'
1758 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001759 """
Jon Halla91c4dc2014-10-22 12:57:04 -04001760 try:
kelvin8ec71442015-01-15 16:57:00 -08001761 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04001762 return None
1763 else:
kelvin8ec71442015-01-15 16:57:00 -08001764 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001765 rawDevices = self.devices()
1766 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08001767 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001768 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08001769 # print "%s in %s?" % ( dpid, device[ 'id' ] )
1770 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04001771 return device
1772 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001773 except TypeError:
1774 main.log.exception( self.name + ": Object not as expected" )
1775 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04001776 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001777 main.log.error( self.name + ": EOF exception found" )
1778 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04001779 main.cleanup()
1780 main.exit()
1781 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001782 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04001783 main.cleanup()
1784 main.exit()
1785
kelvin-onlabd3b64892015-01-20 13:26:24 -08001786 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08001787 """
1788 Checks the number of swithes & links that ONOS sees against the
1789 supplied values. By default this will report to main.log, but the
Jon Hall42db6dc2014-10-24 19:03:48 -04001790 log level can be specifid.
kelvin8ec71442015-01-15 16:57:00 -08001791
Jon Hall42db6dc2014-10-24 19:03:48 -04001792 Params: ip = ip used for the onos cli
1793 numoswitch = expected number of switches
1794 numlink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08001795 logLevel = level to log to. Currently accepts
1796 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04001797
1798
kelvin-onlabd3b64892015-01-20 13:26:24 -08001799 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04001800
kelvin8ec71442015-01-15 16:57:00 -08001801 Returns: main.TRUE if the number of switchs and links are correct,
Jon Hall42db6dc2014-10-24 19:03:48 -04001802 main.FALSE if the numer of switches and links is incorrect,
1803 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08001804 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001805 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001806 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04001807 if topology == {}:
1808 return main.ERROR
1809 output = ""
kelvin8ec71442015-01-15 16:57:00 -08001810 # Is the number of switches is what we expected
1811 devices = topology.get( 'devices', False )
1812 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08001813 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04001814 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08001815 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08001816 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08001817 linkCheck = ( int( links ) == int( numolink ) )
1818 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08001819 # We expected the correct numbers
Jon Hall42db6dc2014-10-24 19:03:48 -04001820 output = output + "The number of links and switches match "\
kelvin8ec71442015-01-15 16:57:00 -08001821 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001822 result = main.TRUE
1823 else:
1824 output = output + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001825 "The number of links and switches does not matc\
1826 h what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04001827 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 output = output + "\n ONOS sees %i devices (%i expected) \
1829 and %i links (%i expected)" % (
1830 int( devices ), int( numoswitch ), int( links ),
1831 int( numolink ) )
1832 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08001833 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001834 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08001835 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04001836 else:
kelvin8ec71442015-01-15 16:57:00 -08001837 main.log.info( output )
1838 return result
Jon Halld4d4b372015-01-28 16:02:41 -08001839 except TypeError:
1840 main.log.exception( self.name + ": Object not as expected" )
1841 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001842 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001843 main.log.error( self.name + ": EOF exception found" )
1844 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001845 main.cleanup()
1846 main.exit()
1847 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001848 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001849 main.cleanup()
1850 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04001851
kelvin-onlabd3b64892015-01-20 13:26:24 -08001852 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08001853 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001854 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08001855 deviceId must be the id of a device as seen in the onos devices command
1856 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04001857 role must be either master, standby, or none
1858
Jon Halle3f39ff2015-01-13 11:50:53 -08001859 Returns:
1860 main.TRUE or main.FALSE based on argument verification and
1861 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001862 """
Jon Hall1c9e8732014-10-27 19:29:27 -04001863 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04001865 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08001866 cmdStr = "device-role " +\
1867 str( deviceId ) + " " +\
1868 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001869 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001870 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001871 if re.search( "Error", handle ):
1872 # end color output to escape any colours
1873 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08001874 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001875 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08001876 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08001877 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04001878 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001879 main.log.error( "Invalid 'role' given to device_role(). " +
1880 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04001881 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001882 except TypeError:
1883 main.log.exception( self.name + ": Object not as expected" )
1884 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04001885 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001886 main.log.error( self.name + ": EOF exception found" )
1887 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04001888 main.cleanup()
1889 main.exit()
1890 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001891 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04001892 main.cleanup()
1893 main.exit()
1894
kelvin-onlabd3b64892015-01-20 13:26:24 -08001895 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001896 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001897 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08001898 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001900 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001901 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001902 if jsonFormat:
1903 cmdStr = "clusters -j"
1904 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001905 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001906 handle variable here contains some ANSI escape color code
1907 sequences at the end which are invisible in the print command
Jon Halle3f39ff2015-01-13 11:50:53 -08001908 output. To make that escape sequence visible, use repr()
kelvin-onlab898a6c62015-01-16 14:13:53 -08001909 function. The repr( handle ) output when printed shows the ANSI
1910 escape sequences. In json.loads( somestring ), this somestring
kelvin-onlabd3b64892015-01-20 13:26:24 -08001911 variable is actually repr( somestring ) and json.loads would
1912 fail with the escape sequence. So we take off that escape
1913 sequence using:
Jon Halle3f39ff2015-01-13 11:50:53 -08001914
kelvin-onlabd3b64892015-01-20 13:26:24 -08001915 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1916 handle1 = ansiEscape.sub( '', handle )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001917 """
kelvin-onlabd3b64892015-01-20 13:26:24 -08001918 ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
1919 handle1 = ansiEscape.sub( '', handle )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001920 return handle1
1921 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001922 cmdStr = "clusters"
1923 handle = self.sendline( cmdStr )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001924 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001925 except TypeError:
1926 main.log.exception( self.name + ": Object not as expected" )
1927 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08001928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001929 main.log.error( self.name + ": EOF exception found" )
1930 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001931 main.cleanup()
1932 main.exit()
1933 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001934 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001935 main.cleanup()
1936 main.exit()
1937
kelvin-onlabd3b64892015-01-20 13:26:24 -08001938 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001939 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001940 CLI command to get the current leader for the Election test application
1941 NOTE: Requires installation of the onos-app-election feature
1942 Returns: Node IP of the leader if one exists
1943 None if none exists
1944 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001945 """
Jon Hall94fd0472014-12-08 11:52:42 -08001946 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001947 cmdStr = "election-test-leader"
1948 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001949 # Leader
1950 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001951 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08001952 nodeSearch = re.search( leaderPattern, response )
1953 if nodeSearch:
1954 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08001955 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001956 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08001957 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08001958 # no leader
1959 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001961 nullSearch = re.search( nullPattern, response )
1962 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08001963 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001964 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08001965 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08001966 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08001967 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08001968 if re.search( errorPattern, response ):
1969 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08001970 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08001971 return main.FALSE
1972 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08001973 main.log.error( "Error in election_test_leader: " +
1974 "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08001975 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08001976 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08001977 except TypeError:
1978 main.log.exception( self.name + ": Object not as expected" )
1979 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001980 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001981 main.log.error( self.name + ": EOF exception found" )
1982 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001983 main.cleanup()
1984 main.exit()
1985 except:
Jon Halld4d4b372015-01-28 16:02:41 -08001986 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001987 main.cleanup()
1988 main.exit()
1989
kelvin-onlabd3b64892015-01-20 13:26:24 -08001990 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001991 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001992 CLI command to run for leadership of the Election test application.
1993 NOTE: Requires installation of the onos-app-election feature
1994 Returns: Main.TRUE on success
1995 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001996 """
Jon Hall94fd0472014-12-08 11:52:42 -08001997 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001998 cmdStr = "election-test-run"
1999 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002000 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002001 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002002 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002003 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002004 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002005 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002006 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002007 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002008 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002009 errorPattern = "Command\snot\sfound"
2010 if re.search( errorPattern, response ):
2011 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002012 return main.FALSE
2013 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002014 main.log.error( "Error in election_test_run: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002015 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002016 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002017 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002018 except TypeError:
2019 main.log.exception( self.name + ": Object not as expected" )
2020 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002021 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002022 main.log.error( self.name + ": EOF exception found" )
2023 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002024 main.cleanup()
2025 main.exit()
2026 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002027 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002028 main.cleanup()
2029 main.exit()
2030
kelvin-onlabd3b64892015-01-20 13:26:24 -08002031 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002032 """
Jon Hall94fd0472014-12-08 11:52:42 -08002033 * CLI command to withdraw the local node from leadership election for
2034 * the Election test application.
2035 #NOTE: Requires installation of the onos-app-election feature
2036 Returns: Main.TRUE on success
2037 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002038 """
Jon Hall94fd0472014-12-08 11:52:42 -08002039 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002040 cmdStr = "election-test-withdraw"
2041 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002042 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002043 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002044 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002045 if re.search( successPattern, response ):
2046 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002047 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002048 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002049 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002050 errorPattern = "Command\snot\sfound"
2051 if re.search( errorPattern, response ):
2052 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002053 return main.FALSE
2054 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002055 main.log.error( "Error in election_test_withdraw: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002056 "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002057 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002058 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002059 except TypeError:
2060 main.log.exception( self.name + ": Object not as expected" )
2061 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002062 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002063 main.log.error( self.name + ": EOF exception found" )
2064 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002065 main.cleanup()
2066 main.exit()
2067 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002068 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002069 main.cleanup()
2070 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002071
kelvin8ec71442015-01-15 16:57:00 -08002072 def getDevicePortsEnabledCount( self, dpid ):
2073 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002074 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002075 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002076 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002077 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002078 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2079 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002080 if re.search( "No such device", output ):
2081 main.log.error( "Error in getting ports" )
2082 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002083 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002084 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002085 except TypeError:
2086 main.log.exception( self.name + ": Object not as expected" )
2087 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002089 main.log.error( self.name + ": EOF exception found" )
2090 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002091 main.cleanup()
2092 main.exit()
2093 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002094 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002095 main.cleanup()
2096 main.exit()
2097
kelvin8ec71442015-01-15 16:57:00 -08002098 def getDeviceLinksActiveCount( self, dpid ):
2099 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002100 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002101 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002102 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002103 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002104 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2105 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002106 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002107 main.log.error( "Error in getting ports " )
2108 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002109 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002110 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002111 except TypeError:
2112 main.log.exception( self.name + ": Object not as expected" )
2113 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002114 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002115 main.log.error( self.name + ": EOF exception found" )
2116 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002117 main.cleanup()
2118 main.exit()
2119 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002120 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002121 main.cleanup()
2122 main.exit()
2123
kelvin8ec71442015-01-15 16:57:00 -08002124 def getAllIntentIds( self ):
2125 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002126 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002127 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002129 cmdStr = "onos:intents | grep id="
2130 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002131 if re.search( "Error", output ):
2132 main.log.error( "Error in getting ports" )
2133 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002134 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002135 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002136 except TypeError:
2137 main.log.exception( self.name + ": Object not as expected" )
2138 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002139 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002140 main.log.error( self.name + ": EOF exception found" )
2141 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002142 main.cleanup()
2143 main.exit()
2144 except:
Jon Halld4d4b372015-01-28 16:02:41 -08002145 main.log.exception( self.name + ": Uncaught exception!" )
2146 main.cleanup()
2147 main.exit()
2148
Jon Hall73509952015-02-24 16:42:56 -08002149 def intentSummary( self ):
2150 """
2151 Returns a dictonary containing the current intent states and the count
2152 """
2153 try:
2154 intents = self.intents( )
2155 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -08002156 for intent in json.loads( intents ): # Iter through intents of a node
Jon Hall73509952015-02-24 16:42:56 -08002157 intentStates.append( intent.get( 'state', None ) )
Jon Hall63604932015-02-26 17:09:50 -08002158 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
2159 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002160 return dict( out )
2161 except TypeError:
2162 main.log.exception( self.name + ": Object not as expected" )
2163 return None
2164 except pexpect.EOF:
2165 main.log.error( self.name + ": EOF exception found" )
2166 main.log.error( self.name + ": " + self.handle.before )
2167 main.cleanup()
2168 main.exit()
2169 except:
2170 main.log.exception( self.name + ": Uncaught exception!" )
2171 main.cleanup()
2172 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002173
2174 def leaders( self ):
2175 """
2176 Returns the output of the leaders command.
2177 """
2178 # FIXME: add json output
2179 try:
2180 output = self.sendline( "onos:leaders" )
2181 main.log.warn( output )
2182 return output
2183 except TypeError:
2184 main.log.exception( self.name + ": Object not as expected" )
2185 return None
2186 except pexpect.EOF:
2187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
2189 main.cleanup()
2190 main.exit()
2191 except:
2192 main.log.exception( self.name + ": Uncaught exception!" )
2193 main.cleanup()
2194 main.exit()
2195
2196 def pendingMap( self ):
2197 """
2198 Returns the output of the intent Pending map.
2199 """
2200 # FIXME: add json output
2201 try:
2202 output = self.sendline( "onos:intents -p" )
2203 main.log.warn( output )
2204 return output
2205 except TypeError:
2206 main.log.exception( self.name + ": Object not as expected" )
2207 return None
2208 except pexpect.EOF:
2209 main.log.error( self.name + ": EOF exception found" )
2210 main.log.error( self.name + ": " + self.handle.before )
2211 main.cleanup()
2212 main.exit()
2213 except:
2214 main.log.exception( self.name + ": Uncaught exception!" )
2215 main.cleanup()
2216 main.exit()
2217
2218 def partitions( self ):
2219 """
2220 Returns the output of the raft partitions command for ONOS.
2221 """
2222 # FIXME: add json output
2223 try:
2224 output = self.sendline( "partitions" )
2225 main.log.warn( output )
2226 return output
2227 except TypeError:
2228 main.log.exception( self.name + ": Object not as expected" )
2229 return None
2230 except pexpect.EOF:
2231 main.log.error( self.name + ": EOF exception found" )
2232 main.log.error( self.name + ": " + self.handle.before )
2233 main.cleanup()
2234 main.exit()
2235 except:
2236 main.log.exception( self.name + ": Uncaught exception!" )
2237 main.cleanup()
2238 main.exit()
2239