blob: 2f8bd47243bbb5b82bc3f712f87ca6589fed4cc9 [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
Jon Hallbd16b922015-03-26 17:53:15 -070024import time
kelvin-onlaba4074292015-07-09 15:19:49 -070025import os
kelvin8ec71442015-01-15 16:57:00 -080026sys.path.append( "../" )
andrewonlab95ce8322014-10-13 14:12:04 -040027from drivers.common.clidriver import CLI
28
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040031
kelvin8ec71442015-01-15 16:57:00 -080032 def __init__( self ):
33 """
34 Initialize client
35 """
Jon Hallefbd9792015-03-05 16:11:36 -080036 self.name = None
37 self.home = None
38 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080039 super( CLI, self ).__init__()
40
41 def connect( self, **connectargs ):
42 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080044 """
andrewonlab95ce8322014-10-13 14:12:04 -040045 try:
46 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080047 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070048 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040049 for key in self.options:
50 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080051 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040052 break
kelvin-onlabfb521662015-02-27 09:52:40 -080053 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070054 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040055
kelvin-onlaba4074292015-07-09 15:19:49 -070056 for key in self.options:
57 if key == 'onosIp':
58 self.onosIp = self.options[ 'onosIp' ]
59 break
60
kelvin8ec71442015-01-15 16:57:00 -080061 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070062
63 try:
64 if os.getenv( str( self.ip_address ) ) != None:
65 self.ip_address = os.getenv( str( self.ip_address ) )
66 else:
67 main.log.info( self.name +
68 ": Trying to connect to " +
69 self.ip_address )
70
71 except KeyError:
72 main.log.info( "Invalid host name," +
73 " connecting to local host instead" )
74 self.ip_address = 'localhost'
75 except Exception as inst:
76 main.log.error( "Uncaught exception: " + str( inst ) )
77
kelvin8ec71442015-01-15 16:57:00 -080078 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080079 user_name=self.user_name,
80 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080081 port=self.port,
82 pwd=self.pwd,
83 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040084
kelvin8ec71442015-01-15 16:57:00 -080085 self.handle.sendline( "cd " + self.home )
86 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040087 if self.handle:
88 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080089 else:
90 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040091 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080092 except TypeError:
93 main.log.exception( self.name + ": Object not as expected" )
94 return None
andrewonlab95ce8322014-10-13 14:12:04 -040095 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080096 main.log.error( self.name + ": EOF exception found" )
97 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040098 main.cleanup()
99 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800100 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800101 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400102 main.cleanup()
103 main.exit()
104
kelvin8ec71442015-01-15 16:57:00 -0800105 def disconnect( self ):
106 """
andrewonlab95ce8322014-10-13 14:12:04 -0400107 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800108 """
Jon Halld61331b2015-02-17 16:35:47 -0800109 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400110 try:
Jon Hall61282e32015-03-19 11:34:11 -0700111 if self.handle:
112 i = self.logout()
113 if i == main.TRUE:
114 self.handle.sendline( "" )
115 self.handle.expect( "\$" )
116 self.handle.sendline( "exit" )
117 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800118 except TypeError:
119 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800120 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400121 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800122 main.log.error( self.name + ": EOF exception found" )
123 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700124 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700125 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700126 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800127 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800128 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400129 response = main.FALSE
130 return response
131
kelvin8ec71442015-01-15 16:57:00 -0800132 def logout( self ):
133 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500134 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700135 Returns main.TRUE if exited CLI and
136 main.FALSE on timeout (not guranteed you are disconnected)
137 None on TypeError
138 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800139 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500140 try:
Jon Hall61282e32015-03-19 11:34:11 -0700141 if self.handle:
142 self.handle.sendline( "" )
143 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
144 timeout=10 )
145 if i == 0: # In ONOS CLI
146 self.handle.sendline( "logout" )
147 self.handle.expect( "\$" )
148 return main.TRUE
149 elif i == 1: # not in CLI
150 return main.TRUE
151 elif i == 3: # Timeout
152 return main.FALSE
153 else:
andrewonlab9627f432014-11-14 12:45:10 -0500154 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800155 except TypeError:
156 main.log.exception( self.name + ": Object not as expected" )
157 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500158 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800159 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700160 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500161 main.cleanup()
162 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700163 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700164 main.log.error( self.name +
165 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800167 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500168 main.cleanup()
169 main.exit()
170
kelvin-onlabd3b64892015-01-20 13:26:24 -0800171 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800172 """
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800174
andrewonlab95ce8322014-10-13 14:12:04 -0400175 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800176 """
andrewonlab95ce8322014-10-13 14:12:04 -0400177 try:
178 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800179 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400180 main.cleanup()
181 main.exit()
182 else:
kelvin8ec71442015-01-15 16:57:00 -0800183 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800184 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800185 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400186 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800187 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800188 handleBefore = self.handle.before
189 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800190 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800191 self.handle.sendline("")
192 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800193 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400194
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 main.log.info( "Cell call returned: " + handleBefore +
196 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400197
198 return main.TRUE
199
Jon Halld4d4b372015-01-28 16:02:41 -0800200 except TypeError:
201 main.log.exception( self.name + ": Object not as expected" )
202 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800204 main.log.error( self.name + ": eof exception found" )
205 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400206 main.cleanup()
207 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800208 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800209 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400210 main.cleanup()
211 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800212
pingping-lin57a56ce2015-05-20 16:43:48 -0700213 def startOnosCli( self, ONOSIp, karafTimeout="",
214 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800215 """
Jon Hallefbd9792015-03-05 16:11:36 -0800216 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 by user would be used to set the current karaf shell idle timeout.
218 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800219 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800220 Below is an example to start a session with 60 seconds idle timeout
221 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800222
Hari Krishna25d42f72015-01-05 15:08:28 -0800223 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800225
kelvin-onlabd3b64892015-01-20 13:26:24 -0800226 Note: karafTimeout is left as str so that this could be read
227 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800228 """
andrewonlab95ce8322014-10-13 14:12:04 -0400229 try:
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.sendline( "" )
231 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700232 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500233
234 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800235 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500236 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400237
kelvin8ec71442015-01-15 16:57:00 -0800238 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800240 i = self.handle.expect( [
241 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700242 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400243
244 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800246 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800247 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800248 "config:property-set -p org.apache.karaf.shell\
249 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800250 karafTimeout )
251 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800252 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400254 return main.TRUE
255 else:
kelvin8ec71442015-01-15 16:57:00 -0800256 # If failed, send ctrl+c to process and try again
257 main.log.info( "Starting CLI failed. Retrying..." )
258 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800260 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
261 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400262 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800264 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800265 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800266 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 "config:property-set -p org.apache.karaf.shell\
268 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800269 karafTimeout )
270 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800272 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400273 return main.TRUE
274 else:
kelvin8ec71442015-01-15 16:57:00 -0800275 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800276 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400277 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400278
Jon Halld4d4b372015-01-28 16:02:41 -0800279 except TypeError:
280 main.log.exception( self.name + ": Object not as expected" )
281 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400282 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800283 main.log.error( self.name + ": EOF exception found" )
284 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400285 main.cleanup()
286 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800287 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800288 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400289 main.cleanup()
290 main.exit()
291
Jon Hallefbd9792015-03-05 16:11:36 -0800292 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800293 """
294 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800295 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800296 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800297 Available level: DEBUG, TRACE, INFO, WARN, ERROR
298 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800299 """
300 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800301 lvlStr = ""
302 if level:
303 lvlStr = "--level=" + level
304
kelvin-onlab9f541032015-02-04 16:19:53 -0800305 self.handle.sendline( "" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700306 i = self.handle.expect( [ "onos>","\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700307 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700308 main.log.error( self.name + ": onos cli session closed." )
309 main.cleanup()
310 main.exit()
311 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700312 self.handle.sendline( "" )
313 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800314 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700315 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800316 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800317
kelvin-onlab9f541032015-02-04 16:19:53 -0800318 response = self.handle.before
319 if re.search( "Error", response ):
320 return main.FALSE
321 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700322 except pexpect.TIMEOUT:
323 main.log.exception( self.name + ": TIMEOUT exception found" )
324 main.cleanup()
325 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800326 except pexpect.EOF:
327 main.log.error( self.name + ": EOF exception found" )
328 main.log.error( self.name + ": " + self.handle.before )
329 main.cleanup()
330 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800331 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800332 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400333 main.cleanup()
334 main.exit()
335
Jon Hallc6358dd2015-04-10 12:44:28 -0700336 def sendline( self, cmdStr, debug=False ):
kelvin8ec71442015-01-15 16:57:00 -0800337 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800338 Send a completely user specified string to
339 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400340 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800341
andrewonlaba18f6bf2014-10-13 19:31:54 -0400342 Warning: There are no sanity checking to commands
343 sent using this method.
kelvin8ec71442015-01-15 16:57:00 -0800344 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400345 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800346 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
347 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800348 self.handle.sendline( cmdStr )
Jon Hall63604932015-02-26 17:09:50 -0800349 i = self.handle.expect( ["onos>", "\$", pexpect.TIMEOUT] )
350 response = self.handle.before
351 if i == 2:
352 self.handle.sendline()
Jon Hallc6358dd2015-04-10 12:44:28 -0700353 self.handle.expect( ["\$", pexpect.TIMEOUT] )
Jon Hall63604932015-02-26 17:09:50 -0800354 response += self.handle.before
355 print response
356 try:
357 print self.handle.after
Jon Hall77ba41c2015-04-06 10:25:40 -0700358 except TypeError:
Jon Hall63604932015-02-26 17:09:50 -0800359 pass
360 # TODO: do something with i
kelvin-onlabd3b64892015-01-20 13:26:24 -0800361 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
kelvin-onlab898a6c62015-01-16 14:13:53 -0800362 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700363 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700364 main.log.debug( self.name + ": Raw output" )
365 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700366
367 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800368 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800369 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700370 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700371 main.log.debug( self.name + ": ansiEscape output" )
372 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700373
kelvin-onlabfb521662015-02-27 09:52:40 -0800374 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800375 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700376 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700377 main.log.debug( self.name + ": Removed extra returns " +
378 "from output" )
379 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700380
381 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800382 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700383 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700384 main.log.debug( self.name + ": parsed and stripped output" )
385 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700386
Jon Hall63604932015-02-26 17:09:50 -0800387 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700388 output = response.split( cmdStr.strip(), 1 )
389 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700390 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700391 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700392 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700393 return output[1].strip()
394 except IndexError:
395 main.log.exception( self.name + ": Object not as expected" )
396 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800397 except TypeError:
398 main.log.exception( self.name + ": Object not as expected" )
399 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400400 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800401 main.log.error( self.name + ": EOF exception found" )
402 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400403 main.cleanup()
404 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800405 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800406 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400407 main.cleanup()
408 main.exit()
409
kelvin8ec71442015-01-15 16:57:00 -0800410 # IMPORTANT NOTE:
411 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800412 # the cli command changing 'a:b' with 'aB'.
413 # Ex ) onos:topology > onosTopology
414 # onos:links > onosLinks
415 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800416
kelvin-onlabd3b64892015-01-20 13:26:24 -0800417 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800418 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400419 Adds a new cluster node by ID and address information.
420 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800421 * nodeId
422 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400423 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800424 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800425 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400426 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800427 cmdStr = "add-node " + str( nodeId ) + " " +\
428 str( ONOSIp ) + " " + str( tcpPort )
429 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -0800430 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800431 main.log.error( "Error in adding node" )
432 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800433 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400434 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800435 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400436 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800437 except TypeError:
438 main.log.exception( self.name + ": Object not as expected" )
439 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800441 main.log.error( self.name + ": EOF exception found" )
442 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400443 main.cleanup()
444 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800445 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800446 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400447 main.cleanup()
448 main.exit()
449
kelvin-onlabd3b64892015-01-20 13:26:24 -0800450 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800451 """
andrewonlab86dc3082014-10-13 18:18:38 -0400452 Removes a cluster by ID
453 Issues command: 'remove-node [<node-id>]'
454 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800455 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800456 """
andrewonlab86dc3082014-10-13 18:18:38 -0400457 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400458
kelvin-onlabd3b64892015-01-20 13:26:24 -0800459 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700460 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700461 if re.search( "Error", handle ):
462 main.log.error( "Error in removing node" )
463 main.log.error( handle )
464 return main.FALSE
465 else:
466 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800467 except TypeError:
468 main.log.exception( self.name + ": Object not as expected" )
469 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400470 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800471 main.log.error( self.name + ": EOF exception found" )
472 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400473 main.cleanup()
474 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800475 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800476 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400477 main.cleanup()
478 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400479
Jon Hall61282e32015-03-19 11:34:11 -0700480 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800481 """
andrewonlab7c211572014-10-15 16:45:20 -0400482 List the nodes currently visible
483 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700484 Optional argument:
485 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800486 """
andrewonlab7c211572014-10-15 16:45:20 -0400487 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700489 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700490 cmdStr += " -j"
491 output = self.sendline( cmdStr )
492 return output
Jon Halld4d4b372015-01-28 16:02:41 -0800493 except TypeError:
494 main.log.exception( self.name + ": Object not as expected" )
495 return None
andrewonlab7c211572014-10-15 16:45:20 -0400496 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800497 main.log.error( self.name + ": EOF exception found" )
498 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400499 main.cleanup()
500 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800501 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800502 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400503 main.cleanup()
504 main.exit()
505
kelvin8ec71442015-01-15 16:57:00 -0800506 def topology( self ):
507 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700508 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700509 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700510 Return:
511 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800512 """
andrewonlab95ce8322014-10-13 14:12:04 -0400513 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700514 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800515 handle = self.sendline( cmdStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700516 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400517 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800518 except TypeError:
519 main.log.exception( self.name + ": Object not as expected" )
520 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800522 main.log.error( self.name + ": EOF exception found" )
523 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400524 main.cleanup()
525 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800526 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800527 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400528 main.cleanup()
529 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800530
kelvin-onlabd3b64892015-01-20 13:26:24 -0800531 def featureInstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800532 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700533 Installs a specified feature by issuing command:
534 'feature:install <feature_str>'
535 NOTE: This is now deprecated, you should use the activateApp method
536 instead
kelvin8ec71442015-01-15 16:57:00 -0800537 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800539 cmdStr = "feature:install " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 handle = self.sendline( cmdStr )
541 if re.search( "Error", handle ):
542 main.log.error( "Error in installing feature" )
543 main.log.error( handle )
544 return main.FALSE
545 else:
546 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800547 except TypeError:
548 main.log.exception( self.name + ": Object not as expected" )
549 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800551 main.log.error( self.name + ": EOF exception found" )
552 main.log.error( self.name + ": " + self.handle.before )
553 main.log.report( "Failed to install feature" )
554 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400555 main.cleanup()
556 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800557 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800558 main.log.exception( self.name + ": Uncaught exception!" )
kelvin8ec71442015-01-15 16:57:00 -0800559 main.log.report( "Failed to install feature" )
560 main.log.report( "Exiting test" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400561 main.cleanup()
562 main.exit()
Jon Halle3f39ff2015-01-13 11:50:53 -0800563
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 def featureUninstall( self, featureStr ):
kelvin8ec71442015-01-15 16:57:00 -0800565 """
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 Uninstalls a specified feature by issuing command:
567 'feature:uninstall <feature_str>'
568 NOTE: This is now deprecated, you should use the deactivateApp method
569 instead
kelvin8ec71442015-01-15 16:57:00 -0800570 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400571 try:
Jon Hall30b82fa2015-03-04 17:15:43 -0800572 cmdStr = 'feature:list -i | grep "' + featureStr + '"'
573 handle = self.sendline( cmdStr )
574 if handle != '':
575 cmdStr = "feature:uninstall " + str( featureStr )
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 output = self.sendline( cmdStr )
Jon Hall30b82fa2015-03-04 17:15:43 -0800577 # TODO: Check for possible error responses from karaf
578 else:
Jon Hallefbd9792015-03-05 16:11:36 -0800579 main.log.info( "Feature needs to be installed before " +
580 "uninstalling it" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700581 return main.TRUE
582 if re.search( "Error", output ):
583 main.log.error( "Error in uninstalling feature" )
584 main.log.error( output )
585 return main.FALSE
586 else:
587 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800588 except TypeError:
589 main.log.exception( self.name + ": Object not as expected" )
590 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400594 main.cleanup()
595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800597 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400598 main.cleanup()
599 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800600
jenkins7ead5a82015-03-13 10:28:21 -0700601 def deviceRemove( self, deviceId ):
602 """
603 Removes particular device from storage
604
605 TODO: refactor this function
606 """
607 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700608 cmdStr = "device-remove " + str( deviceId )
609 handle = self.sendline( cmdStr )
610 if re.search( "Error", handle ):
611 main.log.error( "Error in removing device" )
612 main.log.error( handle )
613 return main.FALSE
614 else:
615 return main.TRUE
jenkins7ead5a82015-03-13 10:28:21 -0700616 except TypeError:
617 main.log.exception( self.name + ": Object not as expected" )
618 return None
619 except pexpect.EOF:
620 main.log.error( self.name + ": EOF exception found" )
621 main.log.error( self.name + ": " + self.handle.before )
622 main.cleanup()
623 main.exit()
624 except Exception:
625 main.log.exception( self.name + ": Uncaught exception!" )
626 main.cleanup()
627 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700628
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800630 """
Jon Hall7b02d952014-10-17 20:14:54 -0400631 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400632 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800634 """
andrewonlab86dc3082014-10-13 18:18:38 -0400635 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 cmdStr += " -j"
639 handle = self.sendline( cmdStr )
640 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800641 except TypeError:
642 main.log.exception( self.name + ": Object not as expected" )
643 return None
andrewonlab7c211572014-10-15 16:45:20 -0400644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800645 main.log.error( self.name + ": EOF exception found" )
646 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400647 main.cleanup()
648 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800649 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800650 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400651 main.cleanup()
652 main.exit()
653
kelvin-onlabd3b64892015-01-20 13:26:24 -0800654 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800655 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800656 This balances the devices across all controllers
657 by issuing command: 'onos> onos:balance-masters'
658 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800659 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800660 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700662 handle = self.sendline( cmdStr )
663 if re.search( "Error", handle ):
664 main.log.error( "Error in balancing masters" )
665 main.log.error( handle )
666 return main.FALSE
667 else:
668 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800675 main.cleanup()
676 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800677 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800678 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800679 main.cleanup()
680 main.exit()
681
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800683 """
Jon Halle8217482014-10-17 13:49:14 -0400684 Lists all core links
685 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800687 """
Jon Halle8217482014-10-17 13:49:14 -0400688 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700689 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 cmdStr += " -j"
692 handle = self.sendline( cmdStr )
693 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
Jon Halle8217482014-10-17 13:49:14 -0400697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400700 main.cleanup()
701 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800703 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400704 main.cleanup()
705 main.exit()
706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Halle8217482014-10-17 13:49:14 -0400709 Lists all ports
710 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800712 """
Jon Halle8217482014-10-17 13:49:14 -0400713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700716 cmdStr += " -j"
717 handle = self.sendline( cmdStr )
718 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800719 except TypeError:
720 main.log.exception( self.name + ": Object not as expected" )
721 return None
Jon Halle8217482014-10-17 13:49:14 -0400722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400725 main.cleanup()
726 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800727 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800728 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400729 main.cleanup()
730 main.exit()
731
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800733 """
Jon Hall983a1702014-10-28 18:44:22 -0400734 Lists all devices and the controllers with roles assigned to them
735 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800737 """
andrewonlab7c211572014-10-15 16:45:20 -0400738 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 cmdStr += " -j"
742 handle = self.sendline( cmdStr )
743 return handle
Jon Halld4d4b372015-01-28 16:02:41 -0800744 except TypeError:
745 main.log.exception( self.name + ": Object not as expected" )
746 return None
Jon Hall983a1702014-10-28 18:44:22 -0400747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400750 main.cleanup()
751 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800752 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800753 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400754 main.cleanup()
755 main.exit()
756
kelvin-onlabd3b64892015-01-20 13:26:24 -0800757 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800758 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800759 Given the a string containing the json representation of the "roles"
760 cli command and a partial or whole device id, returns a json object
761 containing the roles output for the first device whose id contains
762 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400763
764 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800765 A dict of the role assignments for the given device or
766 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800767 """
Jon Hall983a1702014-10-28 18:44:22 -0400768 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400770 return None
771 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800772 rawRoles = self.roles()
773 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800774 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800775 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800776 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400778 return device
779 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800780 except TypeError:
781 main.log.exception( self.name + ": Object not as expected" )
782 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400783 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800784 main.log.error( self.name + ": EOF exception found" )
785 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400786 main.cleanup()
787 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800788 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800789 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400790 main.cleanup()
791 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800792
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800794 """
Jon Hall94fd0472014-12-08 11:52:42 -0800795 Iterates through each device and checks if there is a master assigned
796 Returns: main.TRUE if each device has a master
797 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800798 """
Jon Hall94fd0472014-12-08 11:52:42 -0800799 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800800 rawRoles = self.roles()
801 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800802 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800803 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800804 # print device
805 if device[ 'master' ] == "none":
806 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800807 return main.FALSE
808 return main.TRUE
809
Jon Halld4d4b372015-01-28 16:02:41 -0800810 except TypeError:
811 main.log.exception( self.name + ": Object not as expected" )
812 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800813 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800816 main.cleanup()
817 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800818 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800819 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800820 main.cleanup()
821 main.exit()
822
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800824 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400825 Returns string of paths, and the cost.
826 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800827 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400828 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800829 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
830 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -0800831 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( "Error in getting paths" )
833 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400834 else:
kelvin8ec71442015-01-15 16:57:00 -0800835 path = handle.split( ";" )[ 0 ]
836 cost = handle.split( ";" )[ 1 ]
837 return ( path, cost )
Jon Halld4d4b372015-01-28 16:02:41 -0800838 except TypeError:
839 main.log.exception( self.name + ": Object not as expected" )
840 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400841 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800842 main.log.error( self.name + ": EOF exception found" )
843 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400844 main.cleanup()
845 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800846 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800847 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400848 main.cleanup()
849 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800850
kelvin-onlabd3b64892015-01-20 13:26:24 -0800851 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800852 """
Jon Hallffb386d2014-11-21 13:43:38 -0800853 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400854 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800855 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800856 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400857 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700858 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700860 cmdStr += " -j"
861 handle = self.sendline( cmdStr )
862 return handle
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()
Jon Hallfebb1c72015-03-05 13:30:09 -0800871 except Exception:
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 getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400878 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800879
Jon Hallefbd9792015-03-05 16:11:36 -0800880 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800881 partial mac address
882
Jon Hall42db6dc2014-10-24 19:03:48 -0400883 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800884 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400885 try:
kelvin8ec71442015-01-15 16:57:00 -0800886 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400887 return None
888 else:
889 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800890 rawHosts = self.hosts()
891 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800892 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800893 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800894 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800895 if not host:
896 pass
897 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400898 return host
899 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800900 except TypeError:
901 main.log.exception( self.name + ": Object not as expected" )
902 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400903 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800904 main.log.error( self.name + ": EOF exception found" )
905 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400906 main.cleanup()
907 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800908 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800909 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400910 main.cleanup()
911 main.exit()
912
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800914 """
915 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400916 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800917
andrewonlab3f0a4af2014-10-17 12:25:14 -0400918 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800919 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400920 IMPORTANT:
921 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800922 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400923 Furthermore, it assumes that value of VLAN is '-1'
924 Description:
kelvin8ec71442015-01-15 16:57:00 -0800925 Converts mininet hosts ( h1, h2, h3... ) into
926 ONOS format ( 00:00:00:00:00:01/-1 , ... )
927 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400928 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400930
kelvin-onlabd3b64892015-01-20 13:26:24 -0800931 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800932 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 hostHex = hex( int( host ) ).zfill( 12 )
934 hostHex = str( hostHex ).replace( 'x', '0' )
935 i = iter( str( hostHex ) )
936 hostHex = ":".join( a + b for a, b in zip( i, i ) )
937 hostHex = hostHex + "/-1"
938 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400939
kelvin-onlabd3b64892015-01-20 13:26:24 -0800940 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -0400941
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400948 main.cleanup()
949 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800950 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800951 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400952 main.cleanup()
953 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -0400954
kelvin-onlabd3b64892015-01-20 13:26:24 -0800955 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -0800956 """
andrewonlabe6745342014-10-17 14:29:13 -0400957 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 * hostIdOne: ONOS host id for host1
959 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -0400960 Description:
Jon Hallefbd9792015-03-05 16:11:36 -0800961 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -0500962 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -0800963 Returns:
964 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -0800965 """
andrewonlabe6745342014-10-17 14:29:13 -0400966 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 cmdStr = "add-host-intent " + str( hostIdOne ) +\
968 " " + str( hostIdTwo )
969 handle = self.sendline( cmdStr )
Hari Krishnaac4e1782015-01-26 12:09:12 -0800970 if re.search( "Error", handle ):
971 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -0700972 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800973 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -0800974 else:
975 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -0800976 str( hostIdOne ) + " and " + str( hostIdTwo ) )
977 match = re.search('id=0x([\da-f]+),', handle)
978 if match:
979 return match.group()[3:-1]
980 else:
981 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -0700982 main.log.debug( "Response from ONOS was: " +
983 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -0800984 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800985 except TypeError:
986 main.log.exception( self.name + ": Object not as expected" )
987 return None
andrewonlabe6745342014-10-17 14:29:13 -0400988 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -0400991 main.cleanup()
992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800994 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -0400995 main.cleanup()
996 main.exit()
997
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -0800999 """
andrewonlab7b31d232014-10-24 13:31:47 -04001000 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001001 * ingressDevice: device id of ingress device
1002 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001003 Optional:
1004 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001005 Description:
1006 Adds an optical intent by specifying an ingress and egress device
1007 Returns:
1008 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001009 """
andrewonlab7b31d232014-10-24 13:31:47 -04001010 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1012 " " + str( egressDevice )
1013 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001014 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001015 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001016 main.log.error( "Error in adding Optical intent" )
1017 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001018 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001019 main.log.info( "Optical intent installed between " +
1020 str( ingressDevice ) + " and " +
1021 str( egressDevice ) )
1022 match = re.search('id=0x([\da-f]+),', handle)
1023 if match:
1024 return match.group()[3:-1]
1025 else:
1026 main.log.error( "Error, intent ID not found" )
1027 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001028 except TypeError:
1029 main.log.exception( self.name + ": Object not as expected" )
1030 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001031 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001032 main.log.error( self.name + ": EOF exception found" )
1033 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001034 main.cleanup()
1035 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001036 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001037 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001038 main.cleanup()
1039 main.exit()
1040
kelvin-onlabd3b64892015-01-20 13:26:24 -08001041 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001042 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 ingressDevice,
1044 egressDevice,
1045 portIngress="",
1046 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001047 ethType="",
1048 ethSrc="",
1049 ethDst="",
1050 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001052 ipProto="",
1053 ipSrc="",
1054 ipDst="",
1055 tcpSrc="",
1056 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001057 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001058 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 * ingressDevice: device id of ingress device
1060 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001061 Optional:
1062 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001063 * ethSrc: specify ethSrc ( i.e. src mac addr )
1064 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001065 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001067 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001068 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001069 * ipSrc: specify ip source address
1070 * ipDst: specify ip destination address
1071 * tcpSrc: specify tcp source port
1072 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001073 Description:
kelvin8ec71442015-01-15 16:57:00 -08001074 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001075 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001076 Returns:
1077 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001078
Jon Halle3f39ff2015-01-13 11:50:53 -08001079 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001080 options developers provide for point-to-point
1081 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001082 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001083 try:
kelvin8ec71442015-01-15 16:57:00 -08001084 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001085 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001087 and not ipProto and not ipSrc and not ipDst \
1088 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001089 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001090
andrewonlab289e4b72014-10-21 21:24:18 -04001091 else:
andrewonlab36af3822014-11-18 17:48:18 -05001092 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001093
andrewonlab0c0a6772014-10-22 12:31:18 -04001094 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001095 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001096 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001097 cmd += " --ethSrc " + str( ethSrc )
1098 if ethDst:
1099 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001100 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001101 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001103 cmd += " --lambda "
1104 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001105 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001106 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001107 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001108 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001109 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001110 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001111 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001112 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001113 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001114
kelvin8ec71442015-01-15 16:57:00 -08001115 # Check whether the user appended the port
1116 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 if "/" in ingressDevice:
1118 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001119 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001121 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001122 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001123 # Would it make sense to throw an exception and exit
1124 # the test?
1125 return None
andrewonlab36af3822014-11-18 17:48:18 -05001126
kelvin8ec71442015-01-15 16:57:00 -08001127 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001128 str( ingressDevice ) + "/" +\
1129 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 if "/" in egressDevice:
1132 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001133 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001135 main.log.error( "You must specify the egress port" )
1136 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001137
kelvin8ec71442015-01-15 16:57:00 -08001138 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 str( egressDevice ) + "/" +\
1140 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001141
kelvin-onlab898a6c62015-01-16 14:13:53 -08001142 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001143 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001144 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001145 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001146 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001147 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001148 # TODO: print out all the options in this message?
1149 main.log.info( "Point-to-point intent installed between " +
1150 str( ingressDevice ) + " and " +
1151 str( egressDevice ) )
1152 match = re.search('id=0x([\da-f]+),', handle)
1153 if match:
1154 return match.group()[3:-1]
1155 else:
1156 main.log.error( "Error, intent ID not found" )
1157 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001158 except TypeError:
1159 main.log.exception( self.name + ": Object not as expected" )
1160 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001162 main.log.error( self.name + ": EOF exception found" )
1163 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001164 main.cleanup()
1165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001167 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001168 main.cleanup()
1169 main.exit()
1170
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001172 self,
shahshreyac2f97072015-03-19 17:04:29 -07001173 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001175 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001176 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001177 ethType="",
1178 ethSrc="",
1179 ethDst="",
1180 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001182 ipProto="",
1183 ipSrc="",
1184 ipDst="",
1185 tcpSrc="",
1186 tcpDst="",
1187 setEthSrc="",
1188 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001189 """
shahshreyad0c80432014-12-04 16:56:05 -08001190 Note:
shahshreya70622b12015-03-19 17:19:00 -07001191 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001192 is same. That is, all ingress devices include port numbers
1193 with a "/" or all ingress devices could specify device
1194 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001195 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001196 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001197 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001199 Optional:
1200 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001201 * ethSrc: specify ethSrc ( i.e. src mac addr )
1202 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001203 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001204 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001205 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001206 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001207 * ipSrc: specify ip source address
1208 * ipDst: specify ip destination address
1209 * tcpSrc: specify tcp source port
1210 * tcpDst: specify tcp destination port
1211 * setEthSrc: action to Rewrite Source MAC Address
1212 * setEthDst: action to Rewrite Destination MAC Address
1213 Description:
kelvin8ec71442015-01-15 16:57:00 -08001214 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001215 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001216 Returns:
1217 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001218
Jon Halle3f39ff2015-01-13 11:50:53 -08001219 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001220 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001221 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001222 """
shahshreyad0c80432014-12-04 16:56:05 -08001223 try:
kelvin8ec71442015-01-15 16:57:00 -08001224 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001225 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001227 and not ipProto and not ipSrc and not ipDst\
1228 and not tcpSrc and not tcpDst and not setEthSrc\
1229 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001230 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001231
1232 else:
1233 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001234
shahshreyad0c80432014-12-04 16:56:05 -08001235 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001236 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001237 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001238 cmd += " --ethSrc " + str( ethSrc )
1239 if ethDst:
1240 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001241 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001242 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001244 cmd += " --lambda "
1245 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001246 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001247 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001248 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001249 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001250 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001251 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001252 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001253 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001254 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001255 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001256 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001257 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001258 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001259
kelvin8ec71442015-01-15 16:57:00 -08001260 # Check whether the user appended the port
1261 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001262
1263 if portIngressList is None:
1264 for ingressDevice in ingressDeviceList:
1265 if "/" in ingressDevice:
1266 cmd += " " + str( ingressDevice )
1267 else:
1268 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001269 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001270 # TODO: perhaps more meaningful return
1271 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001272 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001273 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001274 for ingressDevice, portIngress in zip( ingressDeviceList,
1275 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001276 cmd += " " + \
1277 str( ingressDevice ) + "/" +\
1278 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001279 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001280 main.log.error( "Device list and port list does not " +
1281 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001282 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 if "/" in egressDevice:
1284 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001285 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001287 main.log.error( "You must specify " +
1288 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001289 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001290
kelvin8ec71442015-01-15 16:57:00 -08001291 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001292 str( egressDevice ) + "/" +\
1293 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001294 handle = self.sendline( cmd )
kelvin-onlabfb521662015-02-27 09:52:40 -08001295 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001296 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001297 main.log.error( "Error in adding multipoint-to-singlepoint " +
1298 "intent" )
1299 return None
shahshreyad0c80432014-12-04 16:56:05 -08001300 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001301 match = re.search('id=0x([\da-f]+),', handle)
1302 if match:
1303 return match.group()[3:-1]
1304 else:
1305 main.log.error( "Error, intent ID not found" )
1306 return None
1307 except TypeError:
1308 main.log.exception( self.name + ": Object not as expected" )
1309 return None
1310 except pexpect.EOF:
1311 main.log.error( self.name + ": EOF exception found" )
1312 main.log.error( self.name + ": " + self.handle.before )
1313 main.cleanup()
1314 main.exit()
1315 except Exception:
1316 main.log.exception( self.name + ": Uncaught exception!" )
1317 main.cleanup()
1318 main.exit()
1319
1320 def addSinglepointToMultipointIntent(
1321 self,
1322 ingressDevice,
1323 egressDeviceList,
1324 portIngress="",
1325 portEgressList=None,
1326 ethType="",
1327 ethSrc="",
1328 ethDst="",
1329 bandwidth="",
1330 lambdaAlloc=False,
1331 ipProto="",
1332 ipSrc="",
1333 ipDst="",
1334 tcpSrc="",
1335 tcpDst="",
1336 setEthSrc="",
1337 setEthDst="" ):
1338 """
1339 Note:
1340 This function assumes the format of all egress devices
1341 is same. That is, all egress devices include port numbers
1342 with a "/" or all egress devices could specify device
1343 ids and port numbers seperately.
1344 Required:
1345 * EgressDeviceList: List of device ids of egress device
1346 ( Atleast 2 eress devices required in the list )
1347 * ingressDevice: device id of ingress device
1348 Optional:
1349 * ethType: specify ethType
1350 * ethSrc: specify ethSrc ( i.e. src mac addr )
1351 * ethDst: specify ethDst ( i.e. dst mac addr )
1352 * bandwidth: specify bandwidth capacity of link
1353 * lambdaAlloc: if True, intent will allocate lambda
1354 for the specified intent
1355 * ipProto: specify ip protocol
1356 * ipSrc: specify ip source address
1357 * ipDst: specify ip destination address
1358 * tcpSrc: specify tcp source port
1359 * tcpDst: specify tcp destination port
1360 * setEthSrc: action to Rewrite Source MAC Address
1361 * setEthDst: action to Rewrite Destination MAC Address
1362 Description:
1363 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1364 specifying device id's and optional fields
1365 Returns:
1366 A string of the intent id or None on error
1367
1368 NOTE: This function may change depending on the
1369 options developers provide for singlepoint-to-multipoint
1370 intent via cli
1371 """
1372 try:
1373 # If there are no optional arguments
1374 if not ethType and not ethSrc and not ethDst\
1375 and not bandwidth and not lambdaAlloc\
1376 and not ipProto and not ipSrc and not ipDst\
1377 and not tcpSrc and not tcpDst and not setEthSrc\
1378 and not setEthDst:
1379 cmd = "add-single-to-multi-intent"
1380
1381 else:
1382 cmd = "add-single-to-multi-intent"
1383
1384 if ethType:
1385 cmd += " --ethType " + str( ethType )
1386 if ethSrc:
1387 cmd += " --ethSrc " + str( ethSrc )
1388 if ethDst:
1389 cmd += " --ethDst " + str( ethDst )
1390 if bandwidth:
1391 cmd += " --bandwidth " + str( bandwidth )
1392 if lambdaAlloc:
1393 cmd += " --lambda "
1394 if ipProto:
1395 cmd += " --ipProto " + str( ipProto )
1396 if ipSrc:
1397 cmd += " --ipSrc " + str( ipSrc )
1398 if ipDst:
1399 cmd += " --ipDst " + str( ipDst )
1400 if tcpSrc:
1401 cmd += " --tcpSrc " + str( tcpSrc )
1402 if tcpDst:
1403 cmd += " --tcpDst " + str( tcpDst )
1404 if setEthSrc:
1405 cmd += " --setEthSrc " + str( setEthSrc )
1406 if setEthDst:
1407 cmd += " --setEthDst " + str( setEthDst )
1408
1409 # Check whether the user appended the port
1410 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001411
kelvin-onlabb9408212015-04-01 13:34:04 -07001412 if "/" in ingressDevice:
1413 cmd += " " + str( ingressDevice )
1414 else:
1415 if not portIngress:
1416 main.log.error( "You must specify " +
1417 "the Ingress port" )
1418 return main.FALSE
1419
1420 cmd += " " +\
1421 str( ingressDevice ) + "/" +\
1422 str( portIngress )
1423
1424 if portEgressList is None:
1425 for egressDevice in egressDeviceList:
1426 if "/" in egressDevice:
1427 cmd += " " + str( egressDevice )
1428 else:
1429 main.log.error( "You must specify " +
1430 "the egress port" )
1431 # TODO: perhaps more meaningful return
1432 return main.FALSE
1433 else:
1434 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001435 for egressDevice, portEgress in zip( egressDeviceList,
1436 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001437 cmd += " " + \
1438 str( egressDevice ) + "/" +\
1439 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001440 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001441 main.log.error( "Device list and port list does not " +
1442 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001443 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001444 handle = self.sendline( cmd )
1445 # If error, return error message
1446 if re.search( "Error", handle ):
1447 main.log.error( "Error in adding singlepoint-to-multipoint " +
1448 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001449 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001450 else:
1451 match = re.search('id=0x([\da-f]+),', handle)
1452 if match:
1453 return match.group()[3:-1]
1454 else:
1455 main.log.error( "Error, intent ID not found" )
1456 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001457 except TypeError:
1458 main.log.exception( self.name + ": Object not as expected" )
1459 return None
shahshreyad0c80432014-12-04 16:56:05 -08001460 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001461 main.log.error( self.name + ": EOF exception found" )
1462 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001463 main.cleanup()
1464 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001465 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001466 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001467 main.cleanup()
1468 main.exit()
1469
Hari Krishna9e232602015-04-13 17:29:08 -07001470 def addMplsIntent(
1471 self,
1472 ingressDevice,
1473 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001474 ingressPort="",
1475 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001476 ethType="",
1477 ethSrc="",
1478 ethDst="",
1479 bandwidth="",
1480 lambdaAlloc=False,
1481 ipProto="",
1482 ipSrc="",
1483 ipDst="",
1484 tcpSrc="",
1485 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001486 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001487 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001488 priority=""):
1489 """
1490 Required:
1491 * ingressDevice: device id of ingress device
1492 * egressDevice: device id of egress device
1493 Optional:
1494 * ethType: specify ethType
1495 * ethSrc: specify ethSrc ( i.e. src mac addr )
1496 * ethDst: specify ethDst ( i.e. dst mac addr )
1497 * bandwidth: specify bandwidth capacity of link
1498 * lambdaAlloc: if True, intent will allocate lambda
1499 for the specified intent
1500 * ipProto: specify ip protocol
1501 * ipSrc: specify ip source address
1502 * ipDst: specify ip destination address
1503 * tcpSrc: specify tcp source port
1504 * tcpDst: specify tcp destination port
1505 * ingressLabel: Ingress MPLS label
1506 * egressLabel: Egress MPLS label
1507 Description:
1508 Adds MPLS intent by
1509 specifying device id's and optional fields
1510 Returns:
1511 A string of the intent id or None on error
1512
1513 NOTE: This function may change depending on the
1514 options developers provide for MPLS
1515 intent via cli
1516 """
1517 try:
1518 # If there are no optional arguments
1519 if not ethType and not ethSrc and not ethDst\
1520 and not bandwidth and not lambdaAlloc \
1521 and not ipProto and not ipSrc and not ipDst \
1522 and not tcpSrc and not tcpDst and not ingressLabel \
1523 and not egressLabel:
1524 cmd = "add-mpls-intent"
1525
1526 else:
1527 cmd = "add-mpls-intent"
1528
1529 if ethType:
1530 cmd += " --ethType " + str( ethType )
1531 if ethSrc:
1532 cmd += " --ethSrc " + str( ethSrc )
1533 if ethDst:
1534 cmd += " --ethDst " + str( ethDst )
1535 if bandwidth:
1536 cmd += " --bandwidth " + str( bandwidth )
1537 if lambdaAlloc:
1538 cmd += " --lambda "
1539 if ipProto:
1540 cmd += " --ipProto " + str( ipProto )
1541 if ipSrc:
1542 cmd += " --ipSrc " + str( ipSrc )
1543 if ipDst:
1544 cmd += " --ipDst " + str( ipDst )
1545 if tcpSrc:
1546 cmd += " --tcpSrc " + str( tcpSrc )
1547 if tcpDst:
1548 cmd += " --tcpDst " + str( tcpDst )
1549 if ingressLabel:
1550 cmd += " --ingressLabel " + str( ingressLabel )
1551 if egressLabel:
1552 cmd += " --egressLabel " + str( egressLabel )
1553 if priority:
1554 cmd += " --priority " + str( priority )
1555
1556 # Check whether the user appended the port
1557 # or provided it as an input
1558 if "/" in ingressDevice:
1559 cmd += " " + str( ingressDevice )
1560 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001561 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001562 main.log.error( "You must specify the ingress port" )
1563 return None
1564
1565 cmd += " " + \
1566 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001567 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001568
1569 if "/" in egressDevice:
1570 cmd += " " + str( egressDevice )
1571 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001572 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001573 main.log.error( "You must specify the egress port" )
1574 return None
1575
1576 cmd += " " +\
1577 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001578 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001579
1580 handle = self.sendline( cmd )
1581 # If error, return error message
1582 if re.search( "Error", handle ):
1583 main.log.error( "Error in adding mpls intent" )
1584 return None
1585 else:
1586 # TODO: print out all the options in this message?
1587 main.log.info( "MPLS intent installed between " +
1588 str( ingressDevice ) + " and " +
1589 str( egressDevice ) )
1590 match = re.search('id=0x([\da-f]+),', handle)
1591 if match:
1592 return match.group()[3:-1]
1593 else:
1594 main.log.error( "Error, intent ID not found" )
1595 return None
1596 except TypeError:
1597 main.log.exception( self.name + ": Object not as expected" )
1598 return None
1599 except pexpect.EOF:
1600 main.log.error( self.name + ": EOF exception found" )
1601 main.log.error( self.name + ": " + self.handle.before )
1602 main.cleanup()
1603 main.exit()
1604 except Exception:
1605 main.log.exception( self.name + ": Uncaught exception!" )
1606 main.cleanup()
1607 main.exit()
1608
Jon Hallefbd9792015-03-05 16:11:36 -08001609 def removeIntent( self, intentId, app='org.onosproject.cli',
1610 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001611 """
shahshreya1c818fc2015-02-26 13:44:08 -08001612 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001613 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001614 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001615 -p or --purge: Purge the intent from the store after removal
1616
Jon Halle3f39ff2015-01-13 11:50:53 -08001617 Returns:
1618 main.False on error and
1619 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001620 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001621 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001622 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001623 if purge:
1624 cmdStr += " -p"
1625 if sync:
1626 cmdStr += " -s"
1627
1628 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001629 handle = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08001630 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001631 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001632 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001633 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001634 # TODO: Should this be main.TRUE
1635 return handle
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()
Jon Hallfebb1c72015-03-05 13:30:09 -08001644 except Exception:
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
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001649 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001650 """
1651 Purges all WITHDRAWN Intents
1652 """
1653 try:
1654 cmdStr = "purge-intents"
1655 handle = self.sendline( cmdStr )
1656 if re.search( "Error", handle ):
1657 main.log.error( "Error in purging intents" )
1658 return main.FALSE
1659 else:
1660 return main.TRUE
1661 except TypeError:
1662 main.log.exception( self.name + ": Object not as expected" )
1663 return None
1664 except pexpect.EOF:
1665 main.log.error( self.name + ": EOF exception found" )
1666 main.log.error( self.name + ": " + self.handle.before )
1667 main.cleanup()
1668 main.exit()
1669 except Exception:
1670 main.log.exception( self.name + ": Uncaught exception!" )
1671 main.cleanup()
1672 main.exit()
1673
kelvin-onlabd3b64892015-01-20 13:26:24 -08001674 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001675 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001676 NOTE: This method should be used after installing application:
1677 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001678 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001679 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001680 Description:
1681 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001682 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001683 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001684 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001686 cmdStr += " -j"
1687 handle = self.sendline( cmdStr )
pingping-lin8b306ac2014-11-17 18:13:51 -08001688 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001689 except TypeError:
1690 main.log.exception( self.name + ": Object not as expected" )
1691 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001693 main.log.error( self.name + ": EOF exception found" )
1694 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001695 main.cleanup()
1696 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001697 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001698 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001699 main.cleanup()
1700 main.exit()
1701
kelvin-onlabd3b64892015-01-20 13:26:24 -08001702 def intents( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001703 """
andrewonlab377693f2014-10-21 16:00:30 -04001704 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001705 * jsonFormat: enable output formatting in json
andrewonlabe6745342014-10-17 14:29:13 -04001706 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001707 Obtain intents currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001708 """
andrewonlabe6745342014-10-17 14:29:13 -04001709 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001710 cmdStr = "intents"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001711 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001712 cmdStr += " -j"
1713 handle = self.sendline( cmdStr )
andrewonlabe6745342014-10-17 14:29:13 -04001714 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001715 except TypeError:
1716 main.log.exception( self.name + ": Object not as expected" )
1717 return None
andrewonlabe6745342014-10-17 14:29:13 -04001718 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001719 main.log.error( self.name + ": EOF exception found" )
1720 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001721 main.cleanup()
1722 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001723 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001724 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001725 main.cleanup()
1726 main.exit()
1727
kelvin-onlab54400a92015-02-26 18:05:51 -08001728 def getIntentState(self, intentsId, intentsJson=None):
1729 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001730 Check intent state.
1731 Accepts a single intent ID (string type) or a list of intent IDs.
1732 Returns the state(string type) of the id if a single intent ID is
1733 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001734 Returns a dictionary with intent IDs as the key and its
1735 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001736 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001737 intentId: intent ID (string type)
1738 intentsJson: parsed json object from the onos:intents api
1739 Returns:
1740 state = An intent's state- INSTALL,WITHDRAWN etc.
1741 stateDict = Dictionary of intent's state. intent ID as the keys and
1742 state as the values.
1743 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001744 try:
1745 state = "State is Undefined"
1746 if not intentsJson:
Jon Hallefbd9792015-03-05 16:11:36 -08001747 intentsJsonTemp = json.loads( self.intents() )
kelvin-onlab54400a92015-02-26 18:05:51 -08001748 else:
Jon Hallefbd9792015-03-05 16:11:36 -08001749 intentsJsonTemp = json.loads( intentsJson )
1750 if isinstance( intentsId, types.StringType ):
kelvin-onlab54400a92015-02-26 18:05:51 -08001751 for intent in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001752 if intentsId == intent[ 'id' ]:
1753 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001754 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001755 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1756 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001757 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001758 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001759 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001760 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001761 stateDict = {}
kelvin-onlab54400a92015-02-26 18:05:51 -08001762 for intents in intentsJsonTemp:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001763 if intentsId[ i ] == intents[ 'id' ]:
1764 stateDict[ 'state' ] = intents[ 'state' ]
1765 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001766 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001767 break
Jon Hallefbd9792015-03-05 16:11:36 -08001768 if len( intentsId ) != len( dictList ):
1769 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001770 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001771 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001772 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001773 return None
kelvin-onlab54400a92015-02-26 18:05:51 -08001774 except TypeError:
1775 main.log.exception( self.name + ": Object not as expected" )
1776 return None
1777 except pexpect.EOF:
1778 main.log.error( self.name + ": EOF exception found" )
1779 main.log.error( self.name + ": " + self.handle.before )
1780 main.cleanup()
1781 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001782 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001783 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04001784 main.cleanup()
1785 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001786
kelvin-onlabf512e942015-06-08 19:42:59 -07001787 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001788 """
1789 Description:
1790 Check intents state
1791 Required:
1792 intentsId - List of intents ID to be checked
1793 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001794 expectedState - Check the expected state(s) of each intents
1795 state in the list.
1796 *NOTE: You can pass in a list of expected state,
1797 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001798 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001799 Returns main.TRUE only if all intent are the same as expected states
1800 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001801 """
1802 try:
1803 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001804 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001805 intentsDict = self.getIntentState( intentsId )
kelvin-onlabf512e942015-06-08 19:42:59 -07001806
Jon Hall390696c2015-05-05 17:13:41 -07001807 #print "len of intentsDict ", str( len( intentsDict ) )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001808 if len( intentsId ) != len( intentsDict ):
1809 main.log.info( self.name + "There is something wrong " +
1810 "getting intents state" )
1811 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001812
1813 if isinstance( expectedState, types.StringType ):
1814 for intents in intentsDict:
1815 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001816 main.log.debug( self.name + " : Intent ID - " +
1817 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001818 " actual state = " +
1819 intents.get( 'state' )
1820 + " does not equal expected state = "
1821 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001822 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001823
1824 elif isinstance( expectedState, types.ListType ):
1825 for intents in intentsDict:
1826 if not any( state == intents.get( 'state' ) for state in
1827 expectedState ):
1828 main.log.debug( self.name + " : Intent ID - " +
1829 intents.get( 'id' ) +
1830 " actual state = " +
1831 intents.get( 'state' ) +
1832 " does not equal expected states = "
1833 + str( expectedState ) )
1834 returnValue = main.FALSE
1835
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001836 if returnValue == main.TRUE:
1837 main.log.info( self.name + ": All " +
1838 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001839 " intents are in " + str( expectedState ) +
1840 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001841 return returnValue
1842 except TypeError:
1843 main.log.exception( self.name + ": Object not as expected" )
1844 return None
1845 except pexpect.EOF:
1846 main.log.error( self.name + ": EOF exception found" )
1847 main.log.error( self.name + ": " + self.handle.before )
1848 main.cleanup()
1849 main.exit()
1850 except Exception:
1851 main.log.exception( self.name + ": Uncaught exception!" )
1852 main.cleanup()
1853 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04001854
kelvin-onlabd3b64892015-01-20 13:26:24 -08001855 def flows( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001856 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001857 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04001859 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001860 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 """
Shreya Shah0f01c812014-10-26 20:15:28 -04001862 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001863 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001864 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001865 cmdStr += " -j"
1866 handle = self.sendline( cmdStr )
Jon Hall61282e32015-03-19 11:34:11 -07001867 if re.search( "Error:", handle ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001868 main.log.error( self.name + ": flows() response: " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08001869 str( handle ) )
Shreya Shah0f01c812014-10-26 20:15:28 -04001870 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001871 except TypeError:
1872 main.log.exception( self.name + ": Object not as expected" )
1873 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04001874 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001875 main.log.error( self.name + ": EOF exception found" )
1876 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04001877 main.cleanup()
1878 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001879 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001880 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04001881 main.cleanup()
1882 main.exit()
1883
kelvin-onlab4df89f22015-04-13 18:10:23 -07001884 def checkFlowsState( self ):
1885 """
1886 Description:
1887 Check the if all the current flows are in ADDED state or
1888 PENDING_ADD state
1889 Return:
1890 returnValue - Returns main.TRUE only if all flows are in
1891 ADDED state or PENDING_ADD, return main.FALSE
1892 otherwise.
1893 """
1894 try:
1895 tempFlows = json.loads( self.flows() )
kelvin-onlabf0594d72015-05-19 17:25:12 -07001896 #print tempFlows[0]
kelvin-onlab4df89f22015-04-13 18:10:23 -07001897 returnValue = main.TRUE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001898
kelvin-onlab4df89f22015-04-13 18:10:23 -07001899 for device in tempFlows:
1900 for flow in device.get( 'flows' ):
1901 if flow.get( 'state' ) != 'ADDED' and flow.get( 'state' ) != \
1902 'PENDING_ADD':
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001903
kelvin-onlab4df89f22015-04-13 18:10:23 -07001904 main.log.info( self.name + ": flow Id: " +
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07001905 str( flow.get( 'groupId' ) ) +
1906 " | state:" +
1907 str( flow.get( 'state' ) ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07001908 returnValue = main.FALSE
kelvin-onlabf0594d72015-05-19 17:25:12 -07001909
kelvin-onlab4df89f22015-04-13 18:10:23 -07001910 return returnValue
1911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
1914 except pexpect.EOF:
1915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
1917 main.cleanup()
1918 main.exit()
1919 except Exception:
1920 main.log.exception( self.name + ": Uncaught exception!" )
1921 main.cleanup()
1922 main.exit()
1923
kelvin-onlabd3b64892015-01-20 13:26:24 -08001924 def pushTestIntents( self, dpidSrc, dpidDst, numIntents,
Jon Hallefbd9792015-03-05 16:11:36 -08001925 numMult="", appId="", report=True ):
kelvin8ec71442015-01-15 16:57:00 -08001926 """
andrewonlab87852b02014-11-19 18:44:19 -05001927 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08001928 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05001929 a specific point-to-point intent definition
1930 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001931 * dpidSrc: specify source dpid
1932 * dpidDst: specify destination dpid
1933 * numIntents: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05001934 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001935 * numMult: number multiplier for multiplying
andrewonlabb66dfa12014-12-02 15:51:10 -05001936 the number of intents specified
kelvin-onlabd3b64892015-01-20 13:26:24 -08001937 * appId: specify the application id init to further
andrewonlabb66dfa12014-12-02 15:51:10 -05001938 modularize the intents
andrewonlab87852b02014-11-19 18:44:19 -05001939 * report: default True, returns latency information
kelvin8ec71442015-01-15 16:57:00 -08001940 """
andrewonlab87852b02014-11-19 18:44:19 -05001941 try:
kelvin8ec71442015-01-15 16:57:00 -08001942 cmd = "push-test-intents " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001943 str( dpidSrc ) + " " + str( dpidDst ) + " " +\
1944 str( numIntents )
1945 if numMult:
1946 cmd += " " + str( numMult )
1947 # If app id is specified, then numMult
kelvin8ec71442015-01-15 16:57:00 -08001948 # must exist because of the way this command
kelvin-onlabd3b64892015-01-20 13:26:24 -08001949 if appId:
1950 cmd += " " + str( appId )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001951 handle = self.sendline( cmd )
andrewonlab87852b02014-11-19 18:44:19 -05001952 if report:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 latResult = []
kelvin8ec71442015-01-15 16:57:00 -08001954 main.log.info( handle )
1955 # Split result by newline
1956 newline = handle.split( "\r\r\n" )
1957 # Ignore the first object of list, which is empty
1958 newline = newline[ 1: ]
1959 # Some sloppy parsing method to get the latency
andrewonlabb66dfa12014-12-02 15:51:10 -05001960 for result in newline:
kelvin8ec71442015-01-15 16:57:00 -08001961 result = result.split( ": " )
1962 # Append the first result of second parse
kelvin-onlabd3b64892015-01-20 13:26:24 -08001963 latResult.append( result[ 1 ].split( " " )[ 0 ] )
1964 main.log.info( latResult )
1965 return latResult
andrewonlab87852b02014-11-19 18:44:19 -05001966 else:
1967 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -08001968 except TypeError:
1969 main.log.exception( self.name + ": Object not as expected" )
1970 return None
andrewonlab87852b02014-11-19 18:44:19 -05001971 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001972 main.log.error( self.name + ": EOF exception found" )
1973 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05001974 main.cleanup()
1975 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001976 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001977 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05001978 main.cleanup()
1979 main.exit()
1980
kelvin-onlabd3b64892015-01-20 13:26:24 -08001981 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001982 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001983 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001984 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001985 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08001986 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001987 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001988 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001989 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001990 cmdStr += " -j"
1991 handle = self.sendline( cmdStr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001992 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08001993 except TypeError:
1994 main.log.exception( self.name + ": Object not as expected" )
1995 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001996 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001997 main.log.error( self.name + ": EOF exception found" )
1998 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001999 main.cleanup()
2000 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002001 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002002 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002003 main.cleanup()
2004 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002005
kelvin-onlabd3b64892015-01-20 13:26:24 -08002006 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002007 """
2008 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002009 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002011 """
andrewonlab867212a2014-10-22 20:13:38 -04002012 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002013 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002014 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002015 cmdStr += " -j"
2016 handle = self.sendline( cmdStr )
jenkins7ead5a82015-03-13 10:28:21 -07002017 if handle:
2018 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002019 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002020 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002021 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002022 else:
2023 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002024 except TypeError:
2025 main.log.exception( self.name + ": Object not as expected" )
2026 return None
andrewonlab867212a2014-10-22 20:13:38 -04002027 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002028 main.log.error( self.name + ": EOF exception found" )
2029 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002030 main.cleanup()
2031 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002032 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002033 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002034 main.cleanup()
2035 main.exit()
2036
kelvin8ec71442015-01-15 16:57:00 -08002037 # Wrapper functions ****************
2038 # Wrapper functions use existing driver
2039 # functions and extends their use case.
2040 # For example, we may use the output of
2041 # a normal driver function, and parse it
2042 # using a wrapper function
andrewonlab7e4d2d32014-10-15 13:23:21 -04002043
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002045 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002046 Description:
2047 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002048 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002049 try:
kelvin8ec71442015-01-15 16:57:00 -08002050 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002051 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002052 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002053
kelvin8ec71442015-01-15 16:57:00 -08002054 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002055 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2056 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002057 match = re.search('id=0x([\da-f]+),', intents)
2058 if match:
2059 tmpId = match.group()[3:-1]
2060 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002061 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002062
Jon Halld4d4b372015-01-28 16:02:41 -08002063 except TypeError:
2064 main.log.exception( self.name + ": Object not as expected" )
2065 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002067 main.log.error( self.name + ": EOF exception found" )
2068 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002069 main.cleanup()
2070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002072 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002073 main.cleanup()
2074 main.exit()
2075
Jon Hall30b82fa2015-03-04 17:15:43 -08002076 def FlowAddedCount( self, deviceId ):
2077 """
2078 Determine the number of flow rules for the given device id that are
2079 in the added state
2080 """
2081 try:
2082 cmdStr = "flows any " + str( deviceId ) + " | " +\
2083 "grep 'state=ADDED' | wc -l"
2084 handle = self.sendline( cmdStr )
2085 return handle
2086 except pexpect.EOF:
2087 main.log.error( self.name + ": EOF exception found" )
2088 main.log.error( self.name + ": " + self.handle.before )
2089 main.cleanup()
2090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002091 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002092 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002093 main.cleanup()
2094 main.exit()
2095
kelvin-onlabd3b64892015-01-20 13:26:24 -08002096 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002097 """
andrewonlab95ce8322014-10-13 14:12:04 -04002098 Use 'devices' function to obtain list of all devices
2099 and parse the result to obtain a list of all device
2100 id's. Returns this list. Returns empty list if no
2101 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002102 List is ordered sequentially
2103
andrewonlab95ce8322014-10-13 14:12:04 -04002104 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002105 device id, and wish to execute other commands using
andrewonlab95ce8322014-10-13 14:12:04 -04002106 the ids. By obtaining the list of device ids on the fly,
2107 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002108 """
andrewonlab95ce8322014-10-13 14:12:04 -04002109 try:
kelvin8ec71442015-01-15 16:57:00 -08002110 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002111 devicesStr = self.devices( jsonFormat=False )
2112 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002113
kelvin-onlabd3b64892015-01-20 13:26:24 -08002114 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002115 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002116 return idList
kelvin8ec71442015-01-15 16:57:00 -08002117
2118 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002119 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002120 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002121 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002122 # Split list further into arguments before and after string
2123 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 # append to idList
2125 for arg in tempList:
2126 idList.append( arg.split( "id=" )[ 1 ] )
2127 return idList
andrewonlab95ce8322014-10-13 14:12:04 -04002128
Jon Halld4d4b372015-01-28 16:02:41 -08002129 except TypeError:
2130 main.log.exception( self.name + ": Object not as expected" )
2131 return None
andrewonlab95ce8322014-10-13 14:12:04 -04002132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -04002135 main.cleanup()
2136 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002137 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002138 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002139 main.cleanup()
2140 main.exit()
2141
kelvin-onlabd3b64892015-01-20 13:26:24 -08002142 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002143 """
andrewonlab7c211572014-10-15 16:45:20 -04002144 Uses 'nodes' function to obtain list of all nodes
2145 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002146 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002147 Returns:
2148 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002149 """
andrewonlab7c211572014-10-15 16:45:20 -04002150 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002151 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002152 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002153 # Sample nodesStr output
2154 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002156 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002157 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002158 nodesJson = json.loads( nodesStr )
2159 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002160 return idList
kelvin8ec71442015-01-15 16:57:00 -08002161
Jon Halld4d4b372015-01-28 16:02:41 -08002162 except TypeError:
2163 main.log.exception( self.name + ": Object not as expected" )
2164 return None
andrewonlab7c211572014-10-15 16:45:20 -04002165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002168 main.cleanup()
2169 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002170 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002171 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002172 main.cleanup()
2173 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -04002174
kelvin-onlabd3b64892015-01-20 13:26:24 -08002175 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002176 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002177 Return the first device from the devices api whose 'id' contains 'dpid'
2178 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002179 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002180 try:
kelvin8ec71442015-01-15 16:57:00 -08002181 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002182 return None
2183 else:
kelvin8ec71442015-01-15 16:57:00 -08002184 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002185 rawDevices = self.devices()
2186 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002187 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002188 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002189 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2190 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002191 return device
2192 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002193 except TypeError:
2194 main.log.exception( self.name + ": Object not as expected" )
2195 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002196 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002197 main.log.error( self.name + ": EOF exception found" )
2198 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002199 main.cleanup()
2200 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002201 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002202 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002203 main.cleanup()
2204 main.exit()
2205
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002207 """
Jon Hallefbd9792015-03-05 16:11:36 -08002208 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002209 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002210 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002211
Jon Hall42db6dc2014-10-24 19:03:48 -04002212 Params: ip = ip used for the onos cli
2213 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002214 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002215 logLevel = level to log to. Currently accepts
2216 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002217
2218
kelvin-onlabd3b64892015-01-20 13:26:24 -08002219 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002220
Jon Hallefbd9792015-03-05 16:11:36 -08002221 Returns: main.TRUE if the number of switches and links are correct,
2222 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002223 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002224 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002225 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002226 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002227 if topology == {}:
2228 return main.ERROR
2229 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002230 # Is the number of switches is what we expected
2231 devices = topology.get( 'devices', False )
2232 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002233 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002234 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002235 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002236 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002237 linkCheck = ( int( links ) == int( numolink ) )
2238 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002239 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002240 output += "The number of links and switches match " +\
2241 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002242 result = main.TRUE
2243 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002244 output += "The number of links and switches does not match " +\
2245 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002246 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002247 output = output + "\n ONOS sees %i devices (%i expected) \
2248 and %i links (%i expected)" % (
2249 int( devices ), int( numoswitch ), int( links ),
2250 int( numolink ) )
2251 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002252 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002253 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002254 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002255 else:
Jon Hall390696c2015-05-05 17:13:41 -07002256 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002257 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002258 except TypeError:
2259 main.log.exception( self.name + ": Object not as expected" )
2260 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002261 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002262 main.log.error( self.name + ": EOF exception found" )
2263 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002264 main.cleanup()
2265 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002266 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002267 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002268 main.cleanup()
2269 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002270
kelvin-onlabd3b64892015-01-20 13:26:24 -08002271 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002272 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002273 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002274 deviceId must be the id of a device as seen in the onos devices command
2275 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002276 role must be either master, standby, or none
2277
Jon Halle3f39ff2015-01-13 11:50:53 -08002278 Returns:
2279 main.TRUE or main.FALSE based on argument verification and
2280 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002281 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002282 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002283 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002284 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002285 cmdStr = "device-role " +\
2286 str( deviceId ) + " " +\
2287 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002289 handle = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002290 if re.search( "Error", handle ):
2291 # end color output to escape any colours
2292 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002293 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002294 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002295 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002296 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002297 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002298 main.log.error( "Invalid 'role' given to device_role(). " +
2299 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002300 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002301 except TypeError:
2302 main.log.exception( self.name + ": Object not as expected" )
2303 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002305 main.log.error( self.name + ": EOF exception found" )
2306 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002307 main.cleanup()
2308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002310 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002311 main.cleanup()
2312 main.exit()
2313
kelvin-onlabd3b64892015-01-20 13:26:24 -08002314 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002315 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002316 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002317 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002318 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002319 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002320 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002321 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002323 cmdStr += " -j"
2324 handle = self.sendline( cmdStr )
2325 return handle
Jon Halld4d4b372015-01-28 16:02:41 -08002326 except TypeError:
2327 main.log.exception( self.name + ": Object not as expected" )
2328 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002330 main.log.error( self.name + ": EOF exception found" )
2331 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002332 main.cleanup()
2333 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002335 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002336 main.cleanup()
2337 main.exit()
2338
kelvin-onlabd3b64892015-01-20 13:26:24 -08002339 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002340 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002341 CLI command to get the current leader for the Election test application
2342 NOTE: Requires installation of the onos-app-election feature
2343 Returns: Node IP of the leader if one exists
2344 None if none exists
2345 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002346 """
Jon Hall94fd0472014-12-08 11:52:42 -08002347 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002348 cmdStr = "election-test-leader"
2349 response = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002350 # Leader
2351 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002352 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002353 nodeSearch = re.search( leaderPattern, response )
2354 if nodeSearch:
2355 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002356 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002357 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002358 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002359 # no leader
2360 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002361 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002362 nullSearch = re.search( nullPattern, response )
2363 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002364 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002365 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002366 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002367 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002368 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002369 if re.search( errorPattern, response ):
2370 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002371 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002372 return main.FALSE
2373 else:
Jon Hall390696c2015-05-05 17:13:41 -07002374 main.log.error( "Error in electionTestLeader on " + self.name +
2375 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002376 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002377 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002378 except TypeError:
2379 main.log.exception( self.name + ": Object not as expected" )
2380 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002382 main.log.error( self.name + ": EOF exception found" )
2383 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002384 main.cleanup()
2385 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002386 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002387 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002388 main.cleanup()
2389 main.exit()
2390
kelvin-onlabd3b64892015-01-20 13:26:24 -08002391 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002392 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002393 CLI command to run for leadership of the Election test application.
2394 NOTE: Requires installation of the onos-app-election feature
2395 Returns: Main.TRUE on success
2396 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002397 """
Jon Hall94fd0472014-12-08 11:52:42 -08002398 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002399 cmdStr = "election-test-run"
2400 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002401 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002402 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002403 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002404 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002405 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002406 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002407 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002408 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002409 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002410 errorPattern = "Command\snot\sfound"
2411 if re.search( errorPattern, response ):
2412 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002413 return main.FALSE
2414 else:
Jon Hall390696c2015-05-05 17:13:41 -07002415 main.log.error( "Error in electionTestRun on " + self.name +
2416 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002417 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002418 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002419 except TypeError:
2420 main.log.exception( self.name + ": Object not as expected" )
2421 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002422 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002423 main.log.error( self.name + ": EOF exception found" )
2424 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002425 main.cleanup()
2426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002427 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002428 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002429 main.cleanup()
2430 main.exit()
2431
kelvin-onlabd3b64892015-01-20 13:26:24 -08002432 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002433 """
Jon Hall94fd0472014-12-08 11:52:42 -08002434 * CLI command to withdraw the local node from leadership election for
2435 * the Election test application.
2436 #NOTE: Requires installation of the onos-app-election feature
2437 Returns: Main.TRUE on success
2438 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002439 """
Jon Hall94fd0472014-12-08 11:52:42 -08002440 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002441 cmdStr = "election-test-withdraw"
2442 response = self.sendline( cmdStr )
kelvin-onlab898a6c62015-01-16 14:13:53 -08002443 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002444 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002445 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002446 if re.search( successPattern, response ):
2447 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002448 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002449 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002450 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002451 errorPattern = "Command\snot\sfound"
2452 if re.search( errorPattern, response ):
2453 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002454 return main.FALSE
2455 else:
Jon Hall390696c2015-05-05 17:13:41 -07002456 main.log.error( "Error in electionTestWithdraw on " +
2457 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002458 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002459 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -08002460 except TypeError:
2461 main.log.exception( self.name + ": Object not as expected" )
2462 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002463 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002464 main.log.error( self.name + ": EOF exception found" )
2465 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002466 main.cleanup()
2467 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002468 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002469 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002470 main.cleanup()
2471 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002472
kelvin8ec71442015-01-15 16:57:00 -08002473 def getDevicePortsEnabledCount( self, dpid ):
2474 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002475 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002476 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002477 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002478 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002479 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2480 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002481 if re.search( "No such device", output ):
2482 main.log.error( "Error in getting ports" )
2483 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002484 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002485 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002486 except TypeError:
2487 main.log.exception( self.name + ": Object not as expected" )
2488 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002489 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002490 main.log.error( self.name + ": EOF exception found" )
2491 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002492 main.cleanup()
2493 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002494 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002495 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002496 main.cleanup()
2497 main.exit()
2498
kelvin8ec71442015-01-15 16:57:00 -08002499 def getDeviceLinksActiveCount( self, dpid ):
2500 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002501 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002502 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002503 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002504 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002505 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2506 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002507 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002508 main.log.error( "Error in getting ports " )
2509 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002510 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002511 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002512 except TypeError:
2513 main.log.exception( self.name + ": Object not as expected" )
2514 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002515 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002516 main.log.error( self.name + ": EOF exception found" )
2517 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002518 main.cleanup()
2519 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002520 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002521 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002522 main.cleanup()
2523 main.exit()
2524
kelvin8ec71442015-01-15 16:57:00 -08002525 def getAllIntentIds( self ):
2526 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002527 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002528 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002529 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 cmdStr = "onos:intents | grep id="
2531 output = self.sendline( cmdStr )
Jon Halle3f39ff2015-01-13 11:50:53 -08002532 if re.search( "Error", output ):
2533 main.log.error( "Error in getting ports" )
2534 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002535 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002536 return output
Jon Halld4d4b372015-01-28 16:02:41 -08002537 except TypeError:
2538 main.log.exception( self.name + ": Object not as expected" )
2539 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002540 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002541 main.log.error( self.name + ": EOF exception found" )
2542 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002543 main.cleanup()
2544 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002545 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002546 main.log.exception( self.name + ": Uncaught exception!" )
2547 main.cleanup()
2548 main.exit()
2549
Jon Hall73509952015-02-24 16:42:56 -08002550 def intentSummary( self ):
2551 """
Jon Hallefbd9792015-03-05 16:11:36 -08002552 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002553 """
2554 try:
2555 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002556 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002557 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002558 states.append( intent.get( 'state', None ) )
2559 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002560 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002561 return dict( out )
2562 except TypeError:
2563 main.log.exception( self.name + ": Object not as expected" )
2564 return None
2565 except pexpect.EOF:
2566 main.log.error( self.name + ": EOF exception found" )
2567 main.log.error( self.name + ": " + self.handle.before )
2568 main.cleanup()
2569 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002570 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002571 main.log.exception( self.name + ": Uncaught exception!" )
2572 main.cleanup()
2573 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002574
Jon Hall61282e32015-03-19 11:34:11 -07002575 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002576 """
2577 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002578 Optional argument:
2579 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002580 """
Jon Hall63604932015-02-26 17:09:50 -08002581 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002582 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002583 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002584 cmdStr += " -j"
2585 output = self.sendline( cmdStr )
2586 return output
Jon Hall63604932015-02-26 17:09:50 -08002587 except TypeError:
2588 main.log.exception( self.name + ": Object not as expected" )
2589 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002590 except pexpect.EOF:
2591 main.log.error( self.name + ": EOF exception found" )
2592 main.log.error( self.name + ": " + self.handle.before )
2593 main.cleanup()
2594 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002595 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002596 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002597 main.cleanup()
2598 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002599
acsmarsa4a4d1e2015-07-10 16:01:24 -07002600 def leaderCandidates( self, jsonFormat=True ):
2601 """
2602 Returns the output of the leaders -c command.
2603 Optional argument:
2604 * jsonFormat - boolean indicating if you want output in json
2605 """
2606 try:
2607 cmdStr = "onos:leaders -c"
2608 if jsonFormat:
2609 cmdStr += " -j"
2610 output = self.sendline( cmdStr )
2611 return output
2612 except TypeError:
2613 main.log.exception( self.name + ": Object not as expected" )
2614 return None
2615 except pexpect.EOF:
2616 main.log.error( self.name + ": EOF exception found" )
2617 main.log.error( self.name + ": " + self.handle.before )
2618 main.cleanup()
2619 main.exit()
2620 except Exception:
2621 main.log.exception( self.name + ": Uncaught exception!" )
2622 main.cleanup()
2623 main.exit()
2624
2625 def specificLeaderCandidate(self,topic):
2626 """
2627 Returns a list in format [leader,candidate1,candidate2,...] for a given
2628 topic parameter and an empty list if the topic doesn't exist
2629 If no leader is elected leader in the returned list will be "none"
2630 Returns None if there is a type error processing the json object
2631 """
2632 try:
2633 cmdStr = "onos:leaders -c -j"
2634 output = self.sendline( cmdStr )
2635 output = json.loads(output)
2636 results = []
2637 for dict in output:
2638 if dict["topic"] == topic:
2639 leader = dict["leader"]
2640 candidates = re.split(", ",dict["candidates"][1:-1])
2641 results.append(leader)
2642 results.extend(candidates)
2643 return results
2644 except TypeError:
2645 main.log.exception( self.name + ": Object not as expected" )
2646 return None
2647 except pexpect.EOF:
2648 main.log.error( self.name + ": EOF exception found" )
2649 main.log.error( self.name + ": " + self.handle.before )
2650 main.cleanup()
2651 main.exit()
2652 except Exception:
2653 main.log.exception( self.name + ": Uncaught exception!" )
2654 main.cleanup()
2655 main.exit()
2656
Jon Hall61282e32015-03-19 11:34:11 -07002657 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002658 """
2659 Returns the output of the intent Pending map.
2660 """
Jon Hall63604932015-02-26 17:09:50 -08002661 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002662 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002663 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002664 cmdStr += " -j"
2665 output = self.sendline( cmdStr )
2666 return output
Jon Hall63604932015-02-26 17:09:50 -08002667 except TypeError:
2668 main.log.exception( self.name + ": Object not as expected" )
2669 return None
2670 except pexpect.EOF:
2671 main.log.error( self.name + ": EOF exception found" )
2672 main.log.error( self.name + ": " + self.handle.before )
2673 main.cleanup()
2674 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002675 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002676 main.log.exception( self.name + ": Uncaught exception!" )
2677 main.cleanup()
2678 main.exit()
2679
Jon Hall61282e32015-03-19 11:34:11 -07002680 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002681 """
2682 Returns the output of the raft partitions command for ONOS.
2683 """
Jon Hall61282e32015-03-19 11:34:11 -07002684 # Sample JSON
2685 # {
2686 # "leader": "tcp://10.128.30.11:7238",
2687 # "members": [
2688 # "tcp://10.128.30.11:7238",
2689 # "tcp://10.128.30.17:7238",
2690 # "tcp://10.128.30.13:7238",
2691 # ],
2692 # "name": "p1",
2693 # "term": 3
2694 # },
Jon Hall63604932015-02-26 17:09:50 -08002695 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002696 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002697 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002698 cmdStr += " -j"
2699 output = self.sendline( cmdStr )
2700 return output
Jon Hall63604932015-02-26 17:09:50 -08002701 except TypeError:
2702 main.log.exception( self.name + ": Object not as expected" )
2703 return None
2704 except pexpect.EOF:
2705 main.log.error( self.name + ": EOF exception found" )
2706 main.log.error( self.name + ": " + self.handle.before )
2707 main.cleanup()
2708 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002709 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002710 main.log.exception( self.name + ": Uncaught exception!" )
2711 main.cleanup()
2712 main.exit()
2713
Jon Hallbe379602015-03-24 13:39:32 -07002714 def apps( self, jsonFormat=True ):
2715 """
2716 Returns the output of the apps command for ONOS. This command lists
2717 information about installed ONOS applications
2718 """
2719 # Sample JSON object
2720 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2721 # "description":"ONOS OpenFlow protocol southbound providers",
2722 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2723 # "features":"[onos-openflow]","state":"ACTIVE"}]
2724 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002725 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002726 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002727 cmdStr += " -j"
2728 output = self.sendline( cmdStr )
2729 assert "Error executing command" not in output
2730 return output
Jon Hallbe379602015-03-24 13:39:32 -07002731 # FIXME: look at specific exceptions/Errors
2732 except AssertionError:
2733 main.log.error( "Error in processing onos:app command: " +
2734 str( output ) )
2735 return None
2736 except TypeError:
2737 main.log.exception( self.name + ": Object not as expected" )
2738 return None
2739 except pexpect.EOF:
2740 main.log.error( self.name + ": EOF exception found" )
2741 main.log.error( self.name + ": " + self.handle.before )
2742 main.cleanup()
2743 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002744 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002745 main.log.exception( self.name + ": Uncaught exception!" )
2746 main.cleanup()
2747 main.exit()
2748
Jon Hall146f1522015-03-24 15:33:24 -07002749 def appStatus( self, appName ):
2750 """
2751 Uses the onos:apps cli command to return the status of an application.
2752 Returns:
2753 "ACTIVE" - If app is installed and activated
2754 "INSTALLED" - If app is installed and deactivated
2755 "UNINSTALLED" - If app is not installed
2756 None - on error
2757 """
Jon Hall146f1522015-03-24 15:33:24 -07002758 try:
2759 if not isinstance( appName, types.StringType ):
2760 main.log.error( self.name + ".appStatus(): appName must be" +
2761 " a string" )
2762 return None
2763 output = self.apps( jsonFormat=True )
2764 appsJson = json.loads( output )
2765 state = None
2766 for app in appsJson:
2767 if appName == app.get('name'):
2768 state = app.get('state')
2769 break
2770 if state == "ACTIVE" or state == "INSTALLED":
2771 return state
2772 elif state is None:
2773 return "UNINSTALLED"
2774 elif state:
2775 main.log.error( "Unexpected state from 'onos:apps': " +
2776 str( state ) )
2777 return state
2778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return None
2781 except pexpect.EOF:
2782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
2784 main.cleanup()
2785 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002786 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002787 main.log.exception( self.name + ": Uncaught exception!" )
2788 main.cleanup()
2789 main.exit()
2790
Jon Hallbe379602015-03-24 13:39:32 -07002791 def app( self, appName, option ):
2792 """
2793 Interacts with the app command for ONOS. This command manages
2794 application inventory.
2795 """
Jon Hallbe379602015-03-24 13:39:32 -07002796 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002797 # Validate argument types
2798 valid = True
2799 if not isinstance( appName, types.StringType ):
2800 main.log.error( self.name + ".app(): appName must be a " +
2801 "string" )
2802 valid = False
2803 if not isinstance( option, types.StringType ):
2804 main.log.error( self.name + ".app(): option must be a string" )
2805 valid = False
2806 if not valid:
2807 return main.FALSE
2808 # Validate Option
2809 option = option.lower()
2810 # NOTE: Install may become a valid option
2811 if option == "activate":
2812 pass
2813 elif option == "deactivate":
2814 pass
2815 elif option == "uninstall":
2816 pass
2817 else:
2818 # Invalid option
2819 main.log.error( "The ONOS app command argument only takes " +
2820 "the values: (activate|deactivate|uninstall)" +
2821 "; was given '" + option + "'")
2822 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002823 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002824 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002825 if "Error executing command" in output:
2826 main.log.error( "Error in processing onos:app command: " +
2827 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002828 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002829 elif "No such application" in output:
2830 main.log.error( "The application '" + appName +
2831 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002832 return main.FALSE
2833 elif "Command not found:" in output:
2834 main.log.error( "Error in processing onos:app command: " +
2835 str( output ) )
2836 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002837 elif "Unsupported command:" in output:
2838 main.log.error( "Incorrect command given to 'app': " +
2839 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002840 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002841 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002842 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002843 return main.TRUE
2844 except TypeError:
2845 main.log.exception( self.name + ": Object not as expected" )
2846 return main.ERROR
2847 except pexpect.EOF:
2848 main.log.error( self.name + ": EOF exception found" )
2849 main.log.error( self.name + ": " + self.handle.before )
2850 main.cleanup()
2851 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002852 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002853 main.log.exception( self.name + ": Uncaught exception!" )
2854 main.cleanup()
2855 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002856
Jon Hallbd16b922015-03-26 17:53:15 -07002857 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002858 """
2859 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002860 appName is the hierarchical app name, not the feature name
2861 If check is True, method will check the status of the app after the
2862 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002863 Returns main.TRUE if the command was successfully sent
2864 main.FALSE if the cli responded with an error or given
2865 incorrect input
2866 """
2867 try:
2868 if not isinstance( appName, types.StringType ):
2869 main.log.error( self.name + ".activateApp(): appName must be" +
2870 " a string" )
2871 return main.FALSE
2872 status = self.appStatus( appName )
2873 if status == "INSTALLED":
2874 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002875 if check and response == main.TRUE:
2876 for i in range(10): # try 10 times then give up
2877 # TODO: Check with Thomas about this delay
2878 status = self.appStatus( appName )
2879 if status == "ACTIVE":
2880 return main.TRUE
2881 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002882 main.log.debug( "The state of application " +
2883 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002884 time.sleep( 1 )
2885 return main.FALSE
2886 else: # not 'check' or command didn't succeed
2887 return response
Jon Hall146f1522015-03-24 15:33:24 -07002888 elif status == "ACTIVE":
2889 return main.TRUE
2890 elif status == "UNINSTALLED":
2891 main.log.error( self.name + ": Tried to activate the " +
2892 "application '" + appName + "' which is not " +
2893 "installed." )
2894 else:
2895 main.log.error( "Unexpected return value from appStatus: " +
2896 str( status ) )
2897 return main.ERROR
2898 except TypeError:
2899 main.log.exception( self.name + ": Object not as expected" )
2900 return main.ERROR
2901 except pexpect.EOF:
2902 main.log.error( self.name + ": EOF exception found" )
2903 main.log.error( self.name + ": " + self.handle.before )
2904 main.cleanup()
2905 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002906 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002907 main.log.exception( self.name + ": Uncaught exception!" )
2908 main.cleanup()
2909 main.exit()
2910
Jon Hallbd16b922015-03-26 17:53:15 -07002911 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002912 """
2913 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002914 appName is the hierarchical app name, not the feature name
2915 If check is True, method will check the status of the app after the
2916 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002917 Returns main.TRUE if the command was successfully sent
2918 main.FALSE if the cli responded with an error or given
2919 incorrect input
2920 """
2921 try:
2922 if not isinstance( appName, types.StringType ):
2923 main.log.error( self.name + ".deactivateApp(): appName must " +
2924 "be a string" )
2925 return main.FALSE
2926 status = self.appStatus( appName )
2927 if status == "INSTALLED":
2928 return main.TRUE
2929 elif status == "ACTIVE":
2930 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002931 if check and response == main.TRUE:
2932 for i in range(10): # try 10 times then give up
2933 status = self.appStatus( appName )
2934 if status == "INSTALLED":
2935 return main.TRUE
2936 else:
2937 time.sleep( 1 )
2938 return main.FALSE
2939 else: # not check or command didn't succeed
2940 return response
Jon Hall146f1522015-03-24 15:33:24 -07002941 elif status == "UNINSTALLED":
2942 main.log.warn( self.name + ": Tried to deactivate the " +
2943 "application '" + appName + "' which is not " +
2944 "installed." )
2945 return main.TRUE
2946 else:
2947 main.log.error( "Unexpected return value from appStatus: " +
2948 str( status ) )
2949 return main.ERROR
2950 except TypeError:
2951 main.log.exception( self.name + ": Object not as expected" )
2952 return main.ERROR
2953 except pexpect.EOF:
2954 main.log.error( self.name + ": EOF exception found" )
2955 main.log.error( self.name + ": " + self.handle.before )
2956 main.cleanup()
2957 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002958 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002959 main.log.exception( self.name + ": Uncaught exception!" )
2960 main.cleanup()
2961 main.exit()
2962
Jon Hallbd16b922015-03-26 17:53:15 -07002963 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002964 """
2965 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002966 appName is the hierarchical app name, not the feature name
2967 If check is True, method will check the status of the app after the
2968 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002969 Returns main.TRUE if the command was successfully sent
2970 main.FALSE if the cli responded with an error or given
2971 incorrect input
2972 """
2973 # TODO: check with Thomas about the state machine for apps
2974 try:
2975 if not isinstance( appName, types.StringType ):
2976 main.log.error( self.name + ".uninstallApp(): appName must " +
2977 "be a string" )
2978 return main.FALSE
2979 status = self.appStatus( appName )
2980 if status == "INSTALLED":
2981 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002982 if check and response == main.TRUE:
2983 for i in range(10): # try 10 times then give up
2984 status = self.appStatus( appName )
2985 if status == "UNINSTALLED":
2986 return main.TRUE
2987 else:
2988 time.sleep( 1 )
2989 return main.FALSE
2990 else: # not check or command didn't succeed
2991 return response
Jon Hall146f1522015-03-24 15:33:24 -07002992 elif status == "ACTIVE":
2993 main.log.warn( self.name + ": Tried to uninstall the " +
2994 "application '" + appName + "' which is " +
2995 "currently active." )
2996 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002997 if check and response == main.TRUE:
2998 for i in range(10): # try 10 times then give up
2999 status = self.appStatus( appName )
3000 if status == "UNINSTALLED":
3001 return main.TRUE
3002 else:
3003 time.sleep( 1 )
3004 return main.FALSE
3005 else: # not check or command didn't succeed
3006 return response
Jon Hall146f1522015-03-24 15:33:24 -07003007 elif status == "UNINSTALLED":
3008 return main.TRUE
3009 else:
3010 main.log.error( "Unexpected return value from appStatus: " +
3011 str( status ) )
3012 return main.ERROR
3013 except TypeError:
3014 main.log.exception( self.name + ": Object not as expected" )
3015 return main.ERROR
3016 except pexpect.EOF:
3017 main.log.error( self.name + ": EOF exception found" )
3018 main.log.error( self.name + ": " + self.handle.before )
3019 main.cleanup()
3020 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003021 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003022 main.log.exception( self.name + ": Uncaught exception!" )
3023 main.cleanup()
3024 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003025
3026 def appIDs( self, jsonFormat=True ):
3027 """
3028 Show the mappings between app id and app names given by the 'app-ids'
3029 cli command
3030 """
3031 try:
3032 cmdStr = "app-ids"
3033 if jsonFormat:
3034 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003035 output = self.sendline( cmdStr )
3036 assert "Error executing command" not in output
3037 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003038 except AssertionError:
3039 main.log.error( "Error in processing onos:app-ids command: " +
3040 str( output ) )
3041 return None
3042 except TypeError:
3043 main.log.exception( self.name + ": Object not as expected" )
3044 return None
3045 except pexpect.EOF:
3046 main.log.error( self.name + ": EOF exception found" )
3047 main.log.error( self.name + ": " + self.handle.before )
3048 main.cleanup()
3049 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003050 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003051 main.log.exception( self.name + ": Uncaught exception!" )
3052 main.cleanup()
3053 main.exit()
3054
3055 def appToIDCheck( self ):
3056 """
3057 This method will check that each application's ID listed in 'apps' is
3058 the same as the ID listed in 'app-ids'. The check will also check that
3059 there are no duplicate IDs issued. Note that an app ID should be
3060 a globaly unique numerical identifier for app/app-like features. Once
3061 an ID is registered, the ID is never freed up so that if an app is
3062 reinstalled it will have the same ID.
3063
3064 Returns: main.TRUE if the check passes and
3065 main.FALSE if the check fails or
3066 main.ERROR if there is some error in processing the test
3067 """
3068 try:
Jon Hall390696c2015-05-05 17:13:41 -07003069 bail = False
3070 ids = self.appIDs( jsonFormat=True )
3071 if ids:
3072 ids = json.loads( ids )
3073 else:
3074 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3075 bail = True
3076 apps = self.apps( jsonFormat=True )
3077 if apps:
3078 apps = json.loads( apps )
3079 else:
3080 main.log.error( "apps returned nothing:" + repr( apps ) )
3081 bail = True
3082 if bail:
3083 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003084 result = main.TRUE
3085 for app in apps:
3086 appID = app.get( 'id' )
3087 if appID is None:
3088 main.log.error( "Error parsing app: " + str( app ) )
3089 result = main.FALSE
3090 appName = app.get( 'name' )
3091 if appName is None:
3092 main.log.error( "Error parsing app: " + str( app ) )
3093 result = main.FALSE
3094 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003095 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003096 # main.log.debug( "Comparing " + str( app ) + " to " +
3097 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003098 if not current: # if ids doesn't have this id
3099 result = main.FALSE
3100 main.log.error( "'app-ids' does not have the ID for " +
3101 str( appName ) + " that apps does." )
3102 elif len( current ) > 1:
3103 # there is more than one app with this ID
3104 result = main.FALSE
3105 # We will log this later in the method
3106 elif not current[0][ 'name' ] == appName:
3107 currentName = current[0][ 'name' ]
3108 result = main.FALSE
3109 main.log.error( "'app-ids' has " + str( currentName ) +
3110 " registered under id:" + str( appID ) +
3111 " but 'apps' has " + str( appName ) )
3112 else:
3113 pass # id and name match!
3114 # now make sure that app-ids has no duplicates
3115 idsList = []
3116 namesList = []
3117 for item in ids:
3118 idsList.append( item[ 'id' ] )
3119 namesList.append( item[ 'name' ] )
3120 if len( idsList ) != len( set( idsList ) ) or\
3121 len( namesList ) != len( set( namesList ) ):
3122 main.log.error( "'app-ids' has some duplicate entries: \n"
3123 + json.dumps( ids,
3124 sort_keys=True,
3125 indent=4,
3126 separators=( ',', ': ' ) ) )
3127 result = main.FALSE
3128 return result
3129 except ( ValueError, TypeError ):
3130 main.log.exception( self.name + ": Object not as expected" )
3131 return main.ERROR
3132 except pexpect.EOF:
3133 main.log.error( self.name + ": EOF exception found" )
3134 main.log.error( self.name + ": " + self.handle.before )
3135 main.cleanup()
3136 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003137 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003138 main.log.exception( self.name + ": Uncaught exception!" )
3139 main.cleanup()
3140 main.exit()
3141
Jon Hallfb760a02015-04-13 15:35:03 -07003142 def getCfg( self, component=None, propName=None, short=False,
3143 jsonFormat=True ):
3144 """
3145 Get configuration settings from onos cli
3146 Optional arguments:
3147 component - Optionally only list configurations for a specific
3148 component. If None, all components with configurations
3149 are displayed. Case Sensitive string.
3150 propName - If component is specified, propName option will show
3151 only this specific configuration from that component.
3152 Case Sensitive string.
3153 jsonFormat - Returns output as json. Note that this will override
3154 the short option
3155 short - Short, less verbose, version of configurations.
3156 This is overridden by the json option
3157 returns:
3158 Output from cli as a string or None on error
3159 """
3160 try:
3161 baseStr = "cfg"
3162 cmdStr = " get"
3163 componentStr = ""
3164 if component:
3165 componentStr += " " + component
3166 if propName:
3167 componentStr += " " + propName
3168 if jsonFormat:
3169 baseStr += " -j"
3170 elif short:
3171 baseStr += " -s"
3172 output = self.sendline( baseStr + cmdStr + componentStr )
3173 assert "Error executing command" not in output
3174 return output
3175 except AssertionError:
3176 main.log.error( "Error in processing 'cfg get' command: " +
3177 str( output ) )
3178 return None
3179 except TypeError:
3180 main.log.exception( self.name + ": Object not as expected" )
3181 return None
3182 except pexpect.EOF:
3183 main.log.error( self.name + ": EOF exception found" )
3184 main.log.error( self.name + ": " + self.handle.before )
3185 main.cleanup()
3186 main.exit()
3187 except Exception:
3188 main.log.exception( self.name + ": Uncaught exception!" )
3189 main.cleanup()
3190 main.exit()
3191
3192 def setCfg( self, component, propName, value=None, check=True ):
3193 """
3194 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003195 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003196 component - The case sensitive name of the component whose
3197 property is to be set
3198 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003199 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003200 value - The value to set the property to. If None, will unset the
3201 property and revert it to it's default value(if applicable)
3202 check - Boolean, Check whether the option was successfully set this
3203 only applies when a value is given.
3204 returns:
3205 main.TRUE on success or main.FALSE on failure. If check is False,
3206 will return main.TRUE unless there is an error
3207 """
3208 try:
3209 baseStr = "cfg"
3210 cmdStr = " set " + str( component ) + " " + str( propName )
3211 if value is not None:
3212 cmdStr += " " + str( value )
3213 output = self.sendline( baseStr + cmdStr )
3214 assert "Error executing command" not in output
3215 if value and check:
3216 results = self.getCfg( component=str( component ),
3217 propName=str( propName ),
3218 jsonFormat=True )
3219 # Check if current value is what we just set
3220 try:
3221 jsonOutput = json.loads( results )
3222 current = jsonOutput[ 'value' ]
3223 except ( ValueError, TypeError ):
3224 main.log.exception( "Error parsing cfg output" )
3225 main.log.error( "output:" + repr( results ) )
3226 return main.FALSE
3227 if current == str( value ):
3228 return main.TRUE
3229 return main.FALSE
3230 return main.TRUE
3231 except AssertionError:
3232 main.log.error( "Error in processing 'cfg set' command: " +
3233 str( output ) )
3234 return main.FALSE
3235 except TypeError:
3236 main.log.exception( self.name + ": Object not as expected" )
3237 return main.FALSE
3238 except pexpect.EOF:
3239 main.log.error( self.name + ": EOF exception found" )
3240 main.log.error( self.name + ": " + self.handle.before )
3241 main.cleanup()
3242 main.exit()
3243 except Exception:
3244 main.log.exception( self.name + ": Uncaught exception!" )
3245 main.cleanup()
3246 main.exit()
3247
Jon Hall390696c2015-05-05 17:13:41 -07003248 def setTestAdd( self, setName, values ):
3249 """
3250 CLI command to add elements to a distributed set.
3251 Arguments:
3252 setName - The name of the set to add to.
3253 values - The value(s) to add to the set, space seperated.
3254 Example usages:
3255 setTestAdd( "set1", "a b c" )
3256 setTestAdd( "set2", "1" )
3257 returns:
3258 main.TRUE on success OR
3259 main.FALSE if elements were already in the set OR
3260 main.ERROR on error
3261 """
3262 try:
3263 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3264 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003265 try:
3266 # TODO: Maybe make this less hardcoded
3267 # ConsistentMap Exceptions
3268 assert "org.onosproject.store.service" not in output
3269 # Node not leader
3270 assert "java.lang.IllegalStateException" not in output
3271 except AssertionError:
3272 main.log.error( "Error in processing 'set-test-add' " +
3273 "command: " + str( output ) )
3274 retryTime = 30 # Conservative time, given by Madan
3275 main.log.info( "Waiting " + str( retryTime ) +
3276 "seconds before retrying." )
3277 time.sleep( retryTime ) # Due to change in mastership
3278 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003279 assert "Error executing command" not in output
3280 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3281 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3282 main.log.info( self.name + ": " + output )
3283 if re.search( positiveMatch, output):
3284 return main.TRUE
3285 elif re.search( negativeMatch, output):
3286 return main.FALSE
3287 else:
3288 main.log.error( self.name + ": setTestAdd did not" +
3289 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003290 main.log.debug( self.name + " actual: " + repr( output ) )
3291 return main.ERROR
3292 except AssertionError:
3293 main.log.error( "Error in processing 'set-test-add' command: " +
3294 str( output ) )
3295 return main.ERROR
3296 except TypeError:
3297 main.log.exception( self.name + ": Object not as expected" )
3298 return main.ERROR
3299 except pexpect.EOF:
3300 main.log.error( self.name + ": EOF exception found" )
3301 main.log.error( self.name + ": " + self.handle.before )
3302 main.cleanup()
3303 main.exit()
3304 except Exception:
3305 main.log.exception( self.name + ": Uncaught exception!" )
3306 main.cleanup()
3307 main.exit()
3308
3309 def setTestRemove( self, setName, values, clear=False, retain=False ):
3310 """
3311 CLI command to remove elements from a distributed set.
3312 Required arguments:
3313 setName - The name of the set to remove from.
3314 values - The value(s) to remove from the set, space seperated.
3315 Optional arguments:
3316 clear - Clear all elements from the set
3317 retain - Retain only the given values. (intersection of the
3318 original set and the given set)
3319 returns:
3320 main.TRUE on success OR
3321 main.FALSE if the set was not changed OR
3322 main.ERROR on error
3323 """
3324 try:
3325 cmdStr = "set-test-remove "
3326 if clear:
3327 cmdStr += "-c " + str( setName )
3328 elif retain:
3329 cmdStr += "-r " + str( setName ) + " " + str( values )
3330 else:
3331 cmdStr += str( setName ) + " " + str( values )
3332 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003333 try:
3334 # TODO: Maybe make this less hardcoded
3335 # ConsistentMap Exceptions
3336 assert "org.onosproject.store.service" not in output
3337 # Node not leader
3338 assert "java.lang.IllegalStateException" not in output
3339 except AssertionError:
3340 main.log.error( "Error in processing 'set-test-add' " +
3341 "command: " + str( output ) )
3342 retryTime = 30 # Conservative time, given by Madan
3343 main.log.info( "Waiting " + str( retryTime ) +
3344 "seconds before retrying." )
3345 time.sleep( retryTime ) # Due to change in mastership
3346 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003347 assert "Error executing command" not in output
3348 main.log.info( self.name + ": " + output )
3349 if clear:
3350 pattern = "Set " + str( setName ) + " cleared"
3351 if re.search( pattern, output ):
3352 return main.TRUE
3353 elif retain:
3354 positivePattern = str( setName ) + " was pruned to contain " +\
3355 "only elements of set \[(.*)\]"
3356 negativePattern = str( setName ) + " was not changed by " +\
3357 "retaining only elements of the set " +\
3358 "\[(.*)\]"
3359 if re.search( positivePattern, output ):
3360 return main.TRUE
3361 elif re.search( negativePattern, output ):
3362 return main.FALSE
3363 else:
3364 positivePattern = "\[(.*)\] was removed from the set " +\
3365 str( setName )
3366 if ( len( values.split() ) == 1 ):
3367 negativePattern = "\[(.*)\] was not in set " +\
3368 str( setName )
3369 else:
3370 negativePattern = "No element of \[(.*)\] was in set " +\
3371 str( setName )
3372 if re.search( positivePattern, output ):
3373 return main.TRUE
3374 elif re.search( negativePattern, output ):
3375 return main.FALSE
3376 main.log.error( self.name + ": setTestRemove did not" +
3377 " match expected output" )
3378 main.log.debug( self.name + " expected: " + pattern )
3379 main.log.debug( self.name + " actual: " + repr( output ) )
3380 return main.ERROR
3381 except AssertionError:
3382 main.log.error( "Error in processing 'set-test-remove' command: " +
3383 str( output ) )
3384 return main.ERROR
3385 except TypeError:
3386 main.log.exception( self.name + ": Object not as expected" )
3387 return main.ERROR
3388 except pexpect.EOF:
3389 main.log.error( self.name + ": EOF exception found" )
3390 main.log.error( self.name + ": " + self.handle.before )
3391 main.cleanup()
3392 main.exit()
3393 except Exception:
3394 main.log.exception( self.name + ": Uncaught exception!" )
3395 main.cleanup()
3396 main.exit()
3397
3398 def setTestGet( self, setName, values="" ):
3399 """
3400 CLI command to get the elements in a distributed set.
3401 Required arguments:
3402 setName - The name of the set to remove from.
3403 Optional arguments:
3404 values - The value(s) to check if in the set, space seperated.
3405 returns:
3406 main.ERROR on error OR
3407 A list of elements in the set if no optional arguments are
3408 supplied OR
3409 A tuple containing the list then:
3410 main.FALSE if the given values are not in the set OR
3411 main.TRUE if the given values are in the set OR
3412 """
3413 try:
3414 values = str( values ).strip()
3415 setName = str( setName ).strip()
3416 length = len( values.split() )
3417 containsCheck = None
3418 # Patterns to match
3419 setPattern = "\[(.*)\]"
3420 pattern = "Items in set " + setName + ":\n" + setPattern
3421 containsTrue = "Set " + setName + " contains the value " + values
3422 containsFalse = "Set " + setName + " did not contain the value " +\
3423 values
3424 containsAllTrue = "Set " + setName + " contains the the subset " +\
3425 setPattern
3426 containsAllFalse = "Set " + setName + " did not contain the the" +\
3427 " subset " + setPattern
3428
3429 cmdStr = "set-test-get "
3430 cmdStr += setName + " " + values
3431 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003432 try:
3433 # TODO: Maybe make this less hardcoded
3434 # ConsistentMap Exceptions
3435 assert "org.onosproject.store.service" not in output
3436 # Node not leader
3437 assert "java.lang.IllegalStateException" not in output
3438 except AssertionError:
3439 main.log.error( "Error in processing 'set-test-add' " +
3440 "command: " + str( output ) )
3441 retryTime = 30 # Conservative time, given by Madan
3442 main.log.info( "Waiting " + str( retryTime ) +
3443 "seconds before retrying." )
3444 time.sleep( retryTime ) # Due to change in mastership
3445 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003446 assert "Error executing command" not in output
3447 main.log.info( self.name + ": " + output )
3448
3449 if length == 0:
3450 match = re.search( pattern, output )
3451 else: # if given values
3452 if length == 1: # Contains output
3453 patternTrue = pattern + "\n" + containsTrue
3454 patternFalse = pattern + "\n" + containsFalse
3455 else: # ContainsAll output
3456 patternTrue = pattern + "\n" + containsAllTrue
3457 patternFalse = pattern + "\n" + containsAllFalse
3458 matchTrue = re.search( patternTrue, output )
3459 matchFalse = re.search( patternFalse, output )
3460 if matchTrue:
3461 containsCheck = main.TRUE
3462 match = matchTrue
3463 elif matchFalse:
3464 containsCheck = main.FALSE
3465 match = matchFalse
3466 else:
3467 main.log.error( self.name + " setTestGet did not match " +\
3468 "expected output" )
3469 main.log.debug( self.name + " expected: " + pattern )
3470 main.log.debug( self.name + " actual: " + repr( output ) )
3471 match = None
3472 if match:
3473 setMatch = match.group( 1 )
3474 if setMatch == '':
3475 setList = []
3476 else:
3477 setList = setMatch.split( ", " )
3478 if length > 0:
3479 return ( setList, containsCheck )
3480 else:
3481 return setList
3482 else: # no match
3483 main.log.error( self.name + ": setTestGet did not" +
3484 " match expected output" )
3485 main.log.debug( self.name + " expected: " + pattern )
3486 main.log.debug( self.name + " actual: " + repr( output ) )
3487 return main.ERROR
3488 except AssertionError:
3489 main.log.error( "Error in processing 'set-test-get' command: " +
3490 str( output ) )
3491 return main.ERROR
3492 except TypeError:
3493 main.log.exception( self.name + ": Object not as expected" )
3494 return main.ERROR
3495 except pexpect.EOF:
3496 main.log.error( self.name + ": EOF exception found" )
3497 main.log.error( self.name + ": " + self.handle.before )
3498 main.cleanup()
3499 main.exit()
3500 except Exception:
3501 main.log.exception( self.name + ": Uncaught exception!" )
3502 main.cleanup()
3503 main.exit()
3504
3505 def setTestSize( self, setName ):
3506 """
3507 CLI command to get the elements in a distributed set.
3508 Required arguments:
3509 setName - The name of the set to remove from.
3510 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003511 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003512 None on error
3513 """
3514 try:
3515 # TODO: Should this check against the number of elements returned
3516 # and then return true/false based on that?
3517 setName = str( setName ).strip()
3518 # Patterns to match
3519 setPattern = "\[(.*)\]"
3520 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3521 setPattern
3522 cmdStr = "set-test-get -s "
3523 cmdStr += setName
3524 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003525 try:
3526 # TODO: Maybe make this less hardcoded
3527 # ConsistentMap Exceptions
3528 assert "org.onosproject.store.service" not in output
3529 # Node not leader
3530 assert "java.lang.IllegalStateException" not in output
3531 except AssertionError:
3532 main.log.error( "Error in processing 'set-test-add' " +
3533 "command: " + str( output ) )
3534 retryTime = 30 # Conservative time, given by Madan
3535 main.log.info( "Waiting " + str( retryTime ) +
3536 "seconds before retrying." )
3537 time.sleep( retryTime ) # Due to change in mastership
3538 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003539 assert "Error executing command" not in output
3540 main.log.info( self.name + ": " + output )
3541 match = re.search( pattern, output )
3542 if match:
3543 setSize = int( match.group( 1 ) )
3544 setMatch = match.group( 2 )
3545 if len( setMatch.split() ) == setSize:
3546 main.log.info( "The size returned by " + self.name +
3547 " matches the number of elements in " +
3548 "the returned set" )
3549 else:
3550 main.log.error( "The size returned by " + self.name +
3551 " does not match the number of " +
3552 "elements in the returned set." )
3553 return setSize
3554 else: # no match
3555 main.log.error( self.name + ": setTestGet did not" +
3556 " match expected output" )
3557 main.log.debug( self.name + " expected: " + pattern )
3558 main.log.debug( self.name + " actual: " + repr( output ) )
3559 return None
3560 except AssertionError:
3561 main.log.error( "Error in processing 'set-test-get' command: " +
3562 str( output ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003563 return None
Jon Hall390696c2015-05-05 17:13:41 -07003564 except TypeError:
3565 main.log.exception( self.name + ": Object not as expected" )
3566 return None
3567 except pexpect.EOF:
3568 main.log.error( self.name + ": EOF exception found" )
3569 main.log.error( self.name + ": " + self.handle.before )
3570 main.cleanup()
3571 main.exit()
3572 except Exception:
3573 main.log.exception( self.name + ": Uncaught exception!" )
3574 main.cleanup()
3575 main.exit()
3576
Jon Hall80daded2015-05-27 16:07:00 -07003577 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003578 """
3579 Command to list the various counters in the system.
3580 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003581 if jsonFormat, a string of the json object returned by the cli
3582 command
3583 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003584 None on error
3585 """
Jon Hall390696c2015-05-05 17:13:41 -07003586 try:
3587 counters = {}
3588 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003589 if jsonFormat:
3590 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003591 output = self.sendline( cmdStr )
3592 assert "Error executing command" not in output
3593 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003594 return output
Jon Hall390696c2015-05-05 17:13:41 -07003595 except AssertionError:
3596 main.log.error( "Error in processing 'counters' command: " +
3597 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003598 return None
Jon Hall390696c2015-05-05 17:13:41 -07003599 except TypeError:
3600 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003601 return None
Jon Hall390696c2015-05-05 17:13:41 -07003602 except pexpect.EOF:
3603 main.log.error( self.name + ": EOF exception found" )
3604 main.log.error( self.name + ": " + self.handle.before )
3605 main.cleanup()
3606 main.exit()
3607 except Exception:
3608 main.log.exception( self.name + ": Uncaught exception!" )
3609 main.cleanup()
3610 main.exit()
3611
3612 def counterTestIncrement( self, counter, inMemory=False ):
3613 """
3614 CLI command to increment and get a distributed counter.
3615 Required arguments:
3616 counter - The name of the counter to increment.
3617 Optional arguments:
3618 inMemory - use in memory map for the counter
3619 returns:
3620 integer value of the counter or
3621 None on Error
3622 """
3623 try:
3624 counter = str( counter )
3625 cmdStr = "counter-test-increment "
3626 if inMemory:
3627 cmdStr += "-i "
3628 cmdStr += counter
3629 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003630 try:
3631 # TODO: Maybe make this less hardcoded
3632 # ConsistentMap Exceptions
3633 assert "org.onosproject.store.service" not in output
3634 # Node not leader
3635 assert "java.lang.IllegalStateException" not in output
3636 except AssertionError:
3637 main.log.error( "Error in processing 'set-test-add' " +
3638 "command: " + str( output ) )
3639 retryTime = 30 # Conservative time, given by Madan
3640 main.log.info( "Waiting " + str( retryTime ) +
3641 "seconds before retrying." )
3642 time.sleep( retryTime ) # Due to change in mastership
3643 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003644 assert "Error executing command" not in output
3645 main.log.info( self.name + ": " + output )
3646 pattern = counter + " was incremented to (\d+)"
3647 match = re.search( pattern, output )
3648 if match:
3649 return int( match.group( 1 ) )
3650 else:
3651 main.log.error( self.name + ": counterTestIncrement did not" +
3652 " match expected output." )
3653 main.log.debug( self.name + " expected: " + pattern )
3654 main.log.debug( self.name + " actual: " + repr( output ) )
3655 return None
3656 except AssertionError:
3657 main.log.error( "Error in processing 'counter-test-increment'" +
3658 " command: " + str( output ) )
3659 return None
3660 except TypeError:
3661 main.log.exception( self.name + ": Object not as expected" )
3662 return None
3663 except pexpect.EOF:
3664 main.log.error( self.name + ": EOF exception found" )
3665 main.log.error( self.name + ": " + self.handle.before )
3666 main.cleanup()
3667 main.exit()
3668 except Exception:
3669 main.log.exception( self.name + ": Uncaught exception!" )
3670 main.cleanup()
3671 main.exit()
3672
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003673 def summary( self, jsonFormat=True ):
3674 """
3675 Description: Execute summary command in onos
3676 Returns: json object ( summary -j ), returns main.FALSE if there is
3677 no output
3678
3679 """
3680 try:
3681 cmdStr = "summary"
3682 if jsonFormat:
3683 cmdStr += " -j"
3684 handle = self.sendline( cmdStr )
3685
3686 if re.search( "Error:", handle ):
3687 main.log.error( self.name + ": summary() response: " +
3688 str( handle ) )
3689 if not handle:
3690 main.log.error( self.name + ": There is no output in " +
3691 "summary command" )
3692 return main.FALSE
3693 return handle
3694 except TypeError:
3695 main.log.exception( self.name + ": Object not as expected" )
3696 return None
3697 except pexpect.EOF:
3698 main.log.error( self.name + ": EOF exception found" )
3699 main.log.error( self.name + ": " + self.handle.before )
3700 main.cleanup()
3701 main.exit()
3702 except Exception:
3703 main.log.exception( self.name + ": Uncaught exception!" )
3704 main.cleanup()
3705 main.exit()