blob: 870293d3c0f38e8c176c438bd9544377a90e01ef [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 """
2581 # FIXME: add json output
Jon Hall61282e32015-03-19 11:34:11 -07002582 # Sample JSON
2583 # {
2584 # "electedTime": "13m ago",
2585 # "epoch": 4,
2586 # "leader": "10.128.30.17",
2587 # "topic": "intent-partition-3"
2588 # },
Jon Hall63604932015-02-26 17:09:50 -08002589 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002590 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002591 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002592 cmdStr += " -j"
2593 output = self.sendline( cmdStr )
2594 return output
Jon Hall63604932015-02-26 17:09:50 -08002595 except TypeError:
2596 main.log.exception( self.name + ": Object not as expected" )
2597 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002598 except pexpect.EOF:
2599 main.log.error( self.name + ": EOF exception found" )
2600 main.log.error( self.name + ": " + self.handle.before )
2601 main.cleanup()
2602 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002603 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002604 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002605 main.cleanup()
2606 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002607
Jon Hall61282e32015-03-19 11:34:11 -07002608 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002609 """
2610 Returns the output of the intent Pending map.
2611 """
Jon Hall63604932015-02-26 17:09:50 -08002612 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002613 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002614 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002615 cmdStr += " -j"
2616 output = self.sendline( cmdStr )
2617 return output
Jon Hall63604932015-02-26 17:09:50 -08002618 except TypeError:
2619 main.log.exception( self.name + ": Object not as expected" )
2620 return None
2621 except pexpect.EOF:
2622 main.log.error( self.name + ": EOF exception found" )
2623 main.log.error( self.name + ": " + self.handle.before )
2624 main.cleanup()
2625 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002626 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002627 main.log.exception( self.name + ": Uncaught exception!" )
2628 main.cleanup()
2629 main.exit()
2630
Jon Hall61282e32015-03-19 11:34:11 -07002631 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002632 """
2633 Returns the output of the raft partitions command for ONOS.
2634 """
Jon Hall61282e32015-03-19 11:34:11 -07002635 # Sample JSON
2636 # {
2637 # "leader": "tcp://10.128.30.11:7238",
2638 # "members": [
2639 # "tcp://10.128.30.11:7238",
2640 # "tcp://10.128.30.17:7238",
2641 # "tcp://10.128.30.13:7238",
2642 # ],
2643 # "name": "p1",
2644 # "term": 3
2645 # },
Jon Hall63604932015-02-26 17:09:50 -08002646 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002647 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07002648 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002649 cmdStr += " -j"
2650 output = self.sendline( cmdStr )
2651 return output
Jon Hall63604932015-02-26 17:09:50 -08002652 except TypeError:
2653 main.log.exception( self.name + ": Object not as expected" )
2654 return None
2655 except pexpect.EOF:
2656 main.log.error( self.name + ": EOF exception found" )
2657 main.log.error( self.name + ": " + self.handle.before )
2658 main.cleanup()
2659 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002660 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002661 main.log.exception( self.name + ": Uncaught exception!" )
2662 main.cleanup()
2663 main.exit()
2664
Jon Hallbe379602015-03-24 13:39:32 -07002665 def apps( self, jsonFormat=True ):
2666 """
2667 Returns the output of the apps command for ONOS. This command lists
2668 information about installed ONOS applications
2669 """
2670 # Sample JSON object
2671 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
2672 # "description":"ONOS OpenFlow protocol southbound providers",
2673 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
2674 # "features":"[onos-openflow]","state":"ACTIVE"}]
2675 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002676 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07002677 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002678 cmdStr += " -j"
2679 output = self.sendline( cmdStr )
2680 assert "Error executing command" not in output
2681 return output
Jon Hallbe379602015-03-24 13:39:32 -07002682 # FIXME: look at specific exceptions/Errors
2683 except AssertionError:
2684 main.log.error( "Error in processing onos:app command: " +
2685 str( output ) )
2686 return None
2687 except TypeError:
2688 main.log.exception( self.name + ": Object not as expected" )
2689 return None
2690 except pexpect.EOF:
2691 main.log.error( self.name + ": EOF exception found" )
2692 main.log.error( self.name + ": " + self.handle.before )
2693 main.cleanup()
2694 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002695 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002696 main.log.exception( self.name + ": Uncaught exception!" )
2697 main.cleanup()
2698 main.exit()
2699
Jon Hall146f1522015-03-24 15:33:24 -07002700 def appStatus( self, appName ):
2701 """
2702 Uses the onos:apps cli command to return the status of an application.
2703 Returns:
2704 "ACTIVE" - If app is installed and activated
2705 "INSTALLED" - If app is installed and deactivated
2706 "UNINSTALLED" - If app is not installed
2707 None - on error
2708 """
Jon Hall146f1522015-03-24 15:33:24 -07002709 try:
2710 if not isinstance( appName, types.StringType ):
2711 main.log.error( self.name + ".appStatus(): appName must be" +
2712 " a string" )
2713 return None
2714 output = self.apps( jsonFormat=True )
2715 appsJson = json.loads( output )
2716 state = None
2717 for app in appsJson:
2718 if appName == app.get('name'):
2719 state = app.get('state')
2720 break
2721 if state == "ACTIVE" or state == "INSTALLED":
2722 return state
2723 elif state is None:
2724 return "UNINSTALLED"
2725 elif state:
2726 main.log.error( "Unexpected state from 'onos:apps': " +
2727 str( state ) )
2728 return state
2729 except TypeError:
2730 main.log.exception( self.name + ": Object not as expected" )
2731 return None
2732 except pexpect.EOF:
2733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
2735 main.cleanup()
2736 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002737 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002738 main.log.exception( self.name + ": Uncaught exception!" )
2739 main.cleanup()
2740 main.exit()
2741
Jon Hallbe379602015-03-24 13:39:32 -07002742 def app( self, appName, option ):
2743 """
2744 Interacts with the app command for ONOS. This command manages
2745 application inventory.
2746 """
Jon Hallbe379602015-03-24 13:39:32 -07002747 try:
Jon Hallbd16b922015-03-26 17:53:15 -07002748 # Validate argument types
2749 valid = True
2750 if not isinstance( appName, types.StringType ):
2751 main.log.error( self.name + ".app(): appName must be a " +
2752 "string" )
2753 valid = False
2754 if not isinstance( option, types.StringType ):
2755 main.log.error( self.name + ".app(): option must be a string" )
2756 valid = False
2757 if not valid:
2758 return main.FALSE
2759 # Validate Option
2760 option = option.lower()
2761 # NOTE: Install may become a valid option
2762 if option == "activate":
2763 pass
2764 elif option == "deactivate":
2765 pass
2766 elif option == "uninstall":
2767 pass
2768 else:
2769 # Invalid option
2770 main.log.error( "The ONOS app command argument only takes " +
2771 "the values: (activate|deactivate|uninstall)" +
2772 "; was given '" + option + "'")
2773 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07002774 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07002775 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07002776 if "Error executing command" in output:
2777 main.log.error( "Error in processing onos:app command: " +
2778 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07002779 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07002780 elif "No such application" in output:
2781 main.log.error( "The application '" + appName +
2782 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07002783 return main.FALSE
2784 elif "Command not found:" in output:
2785 main.log.error( "Error in processing onos:app command: " +
2786 str( output ) )
2787 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07002788 elif "Unsupported command:" in output:
2789 main.log.error( "Incorrect command given to 'app': " +
2790 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002791 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07002792 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07002793 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07002794 return main.TRUE
2795 except TypeError:
2796 main.log.exception( self.name + ": Object not as expected" )
2797 return main.ERROR
2798 except pexpect.EOF:
2799 main.log.error( self.name + ": EOF exception found" )
2800 main.log.error( self.name + ": " + self.handle.before )
2801 main.cleanup()
2802 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002803 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07002804 main.log.exception( self.name + ": Uncaught exception!" )
2805 main.cleanup()
2806 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07002807
Jon Hallbd16b922015-03-26 17:53:15 -07002808 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002809 """
2810 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002811 appName is the hierarchical app name, not the feature name
2812 If check is True, method will check the status of the app after the
2813 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002814 Returns main.TRUE if the command was successfully sent
2815 main.FALSE if the cli responded with an error or given
2816 incorrect input
2817 """
2818 try:
2819 if not isinstance( appName, types.StringType ):
2820 main.log.error( self.name + ".activateApp(): appName must be" +
2821 " a string" )
2822 return main.FALSE
2823 status = self.appStatus( appName )
2824 if status == "INSTALLED":
2825 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002826 if check and response == main.TRUE:
2827 for i in range(10): # try 10 times then give up
2828 # TODO: Check with Thomas about this delay
2829 status = self.appStatus( appName )
2830 if status == "ACTIVE":
2831 return main.TRUE
2832 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07002833 main.log.debug( "The state of application " +
2834 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07002835 time.sleep( 1 )
2836 return main.FALSE
2837 else: # not 'check' or command didn't succeed
2838 return response
Jon Hall146f1522015-03-24 15:33:24 -07002839 elif status == "ACTIVE":
2840 return main.TRUE
2841 elif status == "UNINSTALLED":
2842 main.log.error( self.name + ": Tried to activate the " +
2843 "application '" + appName + "' which is not " +
2844 "installed." )
2845 else:
2846 main.log.error( "Unexpected return value from appStatus: " +
2847 str( status ) )
2848 return main.ERROR
2849 except TypeError:
2850 main.log.exception( self.name + ": Object not as expected" )
2851 return main.ERROR
2852 except pexpect.EOF:
2853 main.log.error( self.name + ": EOF exception found" )
2854 main.log.error( self.name + ": " + self.handle.before )
2855 main.cleanup()
2856 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002857 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002858 main.log.exception( self.name + ": Uncaught exception!" )
2859 main.cleanup()
2860 main.exit()
2861
Jon Hallbd16b922015-03-26 17:53:15 -07002862 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002863 """
2864 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002865 appName is the hierarchical app name, not the feature name
2866 If check is True, method will check the status of the app after the
2867 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002868 Returns main.TRUE if the command was successfully sent
2869 main.FALSE if the cli responded with an error or given
2870 incorrect input
2871 """
2872 try:
2873 if not isinstance( appName, types.StringType ):
2874 main.log.error( self.name + ".deactivateApp(): appName must " +
2875 "be a string" )
2876 return main.FALSE
2877 status = self.appStatus( appName )
2878 if status == "INSTALLED":
2879 return main.TRUE
2880 elif status == "ACTIVE":
2881 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07002882 if check and response == main.TRUE:
2883 for i in range(10): # try 10 times then give up
2884 status = self.appStatus( appName )
2885 if status == "INSTALLED":
2886 return main.TRUE
2887 else:
2888 time.sleep( 1 )
2889 return main.FALSE
2890 else: # not check or command didn't succeed
2891 return response
Jon Hall146f1522015-03-24 15:33:24 -07002892 elif status == "UNINSTALLED":
2893 main.log.warn( self.name + ": Tried to deactivate the " +
2894 "application '" + appName + "' which is not " +
2895 "installed." )
2896 return main.TRUE
2897 else:
2898 main.log.error( "Unexpected return value from appStatus: " +
2899 str( status ) )
2900 return main.ERROR
2901 except TypeError:
2902 main.log.exception( self.name + ": Object not as expected" )
2903 return main.ERROR
2904 except pexpect.EOF:
2905 main.log.error( self.name + ": EOF exception found" )
2906 main.log.error( self.name + ": " + self.handle.before )
2907 main.cleanup()
2908 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002909 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002910 main.log.exception( self.name + ": Uncaught exception!" )
2911 main.cleanup()
2912 main.exit()
2913
Jon Hallbd16b922015-03-26 17:53:15 -07002914 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07002915 """
2916 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07002917 appName is the hierarchical app name, not the feature name
2918 If check is True, method will check the status of the app after the
2919 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07002920 Returns main.TRUE if the command was successfully sent
2921 main.FALSE if the cli responded with an error or given
2922 incorrect input
2923 """
2924 # TODO: check with Thomas about the state machine for apps
2925 try:
2926 if not isinstance( appName, types.StringType ):
2927 main.log.error( self.name + ".uninstallApp(): appName must " +
2928 "be a string" )
2929 return main.FALSE
2930 status = self.appStatus( appName )
2931 if status == "INSTALLED":
2932 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002933 if check and response == main.TRUE:
2934 for i in range(10): # try 10 times then give up
2935 status = self.appStatus( appName )
2936 if status == "UNINSTALLED":
2937 return main.TRUE
2938 else:
2939 time.sleep( 1 )
2940 return main.FALSE
2941 else: # not check or command didn't succeed
2942 return response
Jon Hall146f1522015-03-24 15:33:24 -07002943 elif status == "ACTIVE":
2944 main.log.warn( self.name + ": Tried to uninstall the " +
2945 "application '" + appName + "' which is " +
2946 "currently active." )
2947 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07002948 if check and response == main.TRUE:
2949 for i in range(10): # try 10 times then give up
2950 status = self.appStatus( appName )
2951 if status == "UNINSTALLED":
2952 return main.TRUE
2953 else:
2954 time.sleep( 1 )
2955 return main.FALSE
2956 else: # not check or command didn't succeed
2957 return response
Jon Hall146f1522015-03-24 15:33:24 -07002958 elif status == "UNINSTALLED":
2959 return main.TRUE
2960 else:
2961 main.log.error( "Unexpected return value from appStatus: " +
2962 str( status ) )
2963 return main.ERROR
2964 except TypeError:
2965 main.log.exception( self.name + ": Object not as expected" )
2966 return main.ERROR
2967 except pexpect.EOF:
2968 main.log.error( self.name + ": EOF exception found" )
2969 main.log.error( self.name + ": " + self.handle.before )
2970 main.cleanup()
2971 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002972 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07002973 main.log.exception( self.name + ": Uncaught exception!" )
2974 main.cleanup()
2975 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07002976
2977 def appIDs( self, jsonFormat=True ):
2978 """
2979 Show the mappings between app id and app names given by the 'app-ids'
2980 cli command
2981 """
2982 try:
2983 cmdStr = "app-ids"
2984 if jsonFormat:
2985 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07002986 output = self.sendline( cmdStr )
2987 assert "Error executing command" not in output
2988 return output
Jon Hallbd16b922015-03-26 17:53:15 -07002989 except AssertionError:
2990 main.log.error( "Error in processing onos:app-ids command: " +
2991 str( output ) )
2992 return None
2993 except TypeError:
2994 main.log.exception( self.name + ": Object not as expected" )
2995 return None
2996 except pexpect.EOF:
2997 main.log.error( self.name + ": EOF exception found" )
2998 main.log.error( self.name + ": " + self.handle.before )
2999 main.cleanup()
3000 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003001 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003002 main.log.exception( self.name + ": Uncaught exception!" )
3003 main.cleanup()
3004 main.exit()
3005
3006 def appToIDCheck( self ):
3007 """
3008 This method will check that each application's ID listed in 'apps' is
3009 the same as the ID listed in 'app-ids'. The check will also check that
3010 there are no duplicate IDs issued. Note that an app ID should be
3011 a globaly unique numerical identifier for app/app-like features. Once
3012 an ID is registered, the ID is never freed up so that if an app is
3013 reinstalled it will have the same ID.
3014
3015 Returns: main.TRUE if the check passes and
3016 main.FALSE if the check fails or
3017 main.ERROR if there is some error in processing the test
3018 """
3019 try:
Jon Hall390696c2015-05-05 17:13:41 -07003020 bail = False
3021 ids = self.appIDs( jsonFormat=True )
3022 if ids:
3023 ids = json.loads( ids )
3024 else:
3025 main.log.error( "app-ids returned nothing:" + repr( ids ) )
3026 bail = True
3027 apps = self.apps( jsonFormat=True )
3028 if apps:
3029 apps = json.loads( apps )
3030 else:
3031 main.log.error( "apps returned nothing:" + repr( apps ) )
3032 bail = True
3033 if bail:
3034 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003035 result = main.TRUE
3036 for app in apps:
3037 appID = app.get( 'id' )
3038 if appID is None:
3039 main.log.error( "Error parsing app: " + str( app ) )
3040 result = main.FALSE
3041 appName = app.get( 'name' )
3042 if appName is None:
3043 main.log.error( "Error parsing app: " + str( app ) )
3044 result = main.FALSE
3045 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003046 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003047 # main.log.debug( "Comparing " + str( app ) + " to " +
3048 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003049 if not current: # if ids doesn't have this id
3050 result = main.FALSE
3051 main.log.error( "'app-ids' does not have the ID for " +
3052 str( appName ) + " that apps does." )
3053 elif len( current ) > 1:
3054 # there is more than one app with this ID
3055 result = main.FALSE
3056 # We will log this later in the method
3057 elif not current[0][ 'name' ] == appName:
3058 currentName = current[0][ 'name' ]
3059 result = main.FALSE
3060 main.log.error( "'app-ids' has " + str( currentName ) +
3061 " registered under id:" + str( appID ) +
3062 " but 'apps' has " + str( appName ) )
3063 else:
3064 pass # id and name match!
3065 # now make sure that app-ids has no duplicates
3066 idsList = []
3067 namesList = []
3068 for item in ids:
3069 idsList.append( item[ 'id' ] )
3070 namesList.append( item[ 'name' ] )
3071 if len( idsList ) != len( set( idsList ) ) or\
3072 len( namesList ) != len( set( namesList ) ):
3073 main.log.error( "'app-ids' has some duplicate entries: \n"
3074 + json.dumps( ids,
3075 sort_keys=True,
3076 indent=4,
3077 separators=( ',', ': ' ) ) )
3078 result = main.FALSE
3079 return result
3080 except ( ValueError, TypeError ):
3081 main.log.exception( self.name + ": Object not as expected" )
3082 return main.ERROR
3083 except pexpect.EOF:
3084 main.log.error( self.name + ": EOF exception found" )
3085 main.log.error( self.name + ": " + self.handle.before )
3086 main.cleanup()
3087 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003088 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003089 main.log.exception( self.name + ": Uncaught exception!" )
3090 main.cleanup()
3091 main.exit()
3092
Jon Hallfb760a02015-04-13 15:35:03 -07003093 def getCfg( self, component=None, propName=None, short=False,
3094 jsonFormat=True ):
3095 """
3096 Get configuration settings from onos cli
3097 Optional arguments:
3098 component - Optionally only list configurations for a specific
3099 component. If None, all components with configurations
3100 are displayed. Case Sensitive string.
3101 propName - If component is specified, propName option will show
3102 only this specific configuration from that component.
3103 Case Sensitive string.
3104 jsonFormat - Returns output as json. Note that this will override
3105 the short option
3106 short - Short, less verbose, version of configurations.
3107 This is overridden by the json option
3108 returns:
3109 Output from cli as a string or None on error
3110 """
3111 try:
3112 baseStr = "cfg"
3113 cmdStr = " get"
3114 componentStr = ""
3115 if component:
3116 componentStr += " " + component
3117 if propName:
3118 componentStr += " " + propName
3119 if jsonFormat:
3120 baseStr += " -j"
3121 elif short:
3122 baseStr += " -s"
3123 output = self.sendline( baseStr + cmdStr + componentStr )
3124 assert "Error executing command" not in output
3125 return output
3126 except AssertionError:
3127 main.log.error( "Error in processing 'cfg get' command: " +
3128 str( output ) )
3129 return None
3130 except TypeError:
3131 main.log.exception( self.name + ": Object not as expected" )
3132 return None
3133 except pexpect.EOF:
3134 main.log.error( self.name + ": EOF exception found" )
3135 main.log.error( self.name + ": " + self.handle.before )
3136 main.cleanup()
3137 main.exit()
3138 except Exception:
3139 main.log.exception( self.name + ": Uncaught exception!" )
3140 main.cleanup()
3141 main.exit()
3142
3143 def setCfg( self, component, propName, value=None, check=True ):
3144 """
3145 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003146 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003147 component - The case sensitive name of the component whose
3148 property is to be set
3149 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003150 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003151 value - The value to set the property to. If None, will unset the
3152 property and revert it to it's default value(if applicable)
3153 check - Boolean, Check whether the option was successfully set this
3154 only applies when a value is given.
3155 returns:
3156 main.TRUE on success or main.FALSE on failure. If check is False,
3157 will return main.TRUE unless there is an error
3158 """
3159 try:
3160 baseStr = "cfg"
3161 cmdStr = " set " + str( component ) + " " + str( propName )
3162 if value is not None:
3163 cmdStr += " " + str( value )
3164 output = self.sendline( baseStr + cmdStr )
3165 assert "Error executing command" not in output
3166 if value and check:
3167 results = self.getCfg( component=str( component ),
3168 propName=str( propName ),
3169 jsonFormat=True )
3170 # Check if current value is what we just set
3171 try:
3172 jsonOutput = json.loads( results )
3173 current = jsonOutput[ 'value' ]
3174 except ( ValueError, TypeError ):
3175 main.log.exception( "Error parsing cfg output" )
3176 main.log.error( "output:" + repr( results ) )
3177 return main.FALSE
3178 if current == str( value ):
3179 return main.TRUE
3180 return main.FALSE
3181 return main.TRUE
3182 except AssertionError:
3183 main.log.error( "Error in processing 'cfg set' command: " +
3184 str( output ) )
3185 return main.FALSE
3186 except TypeError:
3187 main.log.exception( self.name + ": Object not as expected" )
3188 return main.FALSE
3189 except pexpect.EOF:
3190 main.log.error( self.name + ": EOF exception found" )
3191 main.log.error( self.name + ": " + self.handle.before )
3192 main.cleanup()
3193 main.exit()
3194 except Exception:
3195 main.log.exception( self.name + ": Uncaught exception!" )
3196 main.cleanup()
3197 main.exit()
3198
Jon Hall390696c2015-05-05 17:13:41 -07003199 def setTestAdd( self, setName, values ):
3200 """
3201 CLI command to add elements to a distributed set.
3202 Arguments:
3203 setName - The name of the set to add to.
3204 values - The value(s) to add to the set, space seperated.
3205 Example usages:
3206 setTestAdd( "set1", "a b c" )
3207 setTestAdd( "set2", "1" )
3208 returns:
3209 main.TRUE on success OR
3210 main.FALSE if elements were already in the set OR
3211 main.ERROR on error
3212 """
3213 try:
3214 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3215 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003216 try:
3217 # TODO: Maybe make this less hardcoded
3218 # ConsistentMap Exceptions
3219 assert "org.onosproject.store.service" not in output
3220 # Node not leader
3221 assert "java.lang.IllegalStateException" not in output
3222 except AssertionError:
3223 main.log.error( "Error in processing 'set-test-add' " +
3224 "command: " + str( output ) )
3225 retryTime = 30 # Conservative time, given by Madan
3226 main.log.info( "Waiting " + str( retryTime ) +
3227 "seconds before retrying." )
3228 time.sleep( retryTime ) # Due to change in mastership
3229 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003230 assert "Error executing command" not in output
3231 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3232 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3233 main.log.info( self.name + ": " + output )
3234 if re.search( positiveMatch, output):
3235 return main.TRUE
3236 elif re.search( negativeMatch, output):
3237 return main.FALSE
3238 else:
3239 main.log.error( self.name + ": setTestAdd did not" +
3240 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003241 main.log.debug( self.name + " actual: " + repr( output ) )
3242 return main.ERROR
3243 except AssertionError:
3244 main.log.error( "Error in processing 'set-test-add' command: " +
3245 str( output ) )
3246 return main.ERROR
3247 except TypeError:
3248 main.log.exception( self.name + ": Object not as expected" )
3249 return main.ERROR
3250 except pexpect.EOF:
3251 main.log.error( self.name + ": EOF exception found" )
3252 main.log.error( self.name + ": " + self.handle.before )
3253 main.cleanup()
3254 main.exit()
3255 except Exception:
3256 main.log.exception( self.name + ": Uncaught exception!" )
3257 main.cleanup()
3258 main.exit()
3259
3260 def setTestRemove( self, setName, values, clear=False, retain=False ):
3261 """
3262 CLI command to remove elements from a distributed set.
3263 Required arguments:
3264 setName - The name of the set to remove from.
3265 values - The value(s) to remove from the set, space seperated.
3266 Optional arguments:
3267 clear - Clear all elements from the set
3268 retain - Retain only the given values. (intersection of the
3269 original set and the given set)
3270 returns:
3271 main.TRUE on success OR
3272 main.FALSE if the set was not changed OR
3273 main.ERROR on error
3274 """
3275 try:
3276 cmdStr = "set-test-remove "
3277 if clear:
3278 cmdStr += "-c " + str( setName )
3279 elif retain:
3280 cmdStr += "-r " + str( setName ) + " " + str( values )
3281 else:
3282 cmdStr += str( setName ) + " " + str( values )
3283 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003284 try:
3285 # TODO: Maybe make this less hardcoded
3286 # ConsistentMap Exceptions
3287 assert "org.onosproject.store.service" not in output
3288 # Node not leader
3289 assert "java.lang.IllegalStateException" not in output
3290 except AssertionError:
3291 main.log.error( "Error in processing 'set-test-add' " +
3292 "command: " + str( output ) )
3293 retryTime = 30 # Conservative time, given by Madan
3294 main.log.info( "Waiting " + str( retryTime ) +
3295 "seconds before retrying." )
3296 time.sleep( retryTime ) # Due to change in mastership
3297 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003298 assert "Error executing command" not in output
3299 main.log.info( self.name + ": " + output )
3300 if clear:
3301 pattern = "Set " + str( setName ) + " cleared"
3302 if re.search( pattern, output ):
3303 return main.TRUE
3304 elif retain:
3305 positivePattern = str( setName ) + " was pruned to contain " +\
3306 "only elements of set \[(.*)\]"
3307 negativePattern = str( setName ) + " was not changed by " +\
3308 "retaining only elements of the set " +\
3309 "\[(.*)\]"
3310 if re.search( positivePattern, output ):
3311 return main.TRUE
3312 elif re.search( negativePattern, output ):
3313 return main.FALSE
3314 else:
3315 positivePattern = "\[(.*)\] was removed from the set " +\
3316 str( setName )
3317 if ( len( values.split() ) == 1 ):
3318 negativePattern = "\[(.*)\] was not in set " +\
3319 str( setName )
3320 else:
3321 negativePattern = "No element of \[(.*)\] was in set " +\
3322 str( setName )
3323 if re.search( positivePattern, output ):
3324 return main.TRUE
3325 elif re.search( negativePattern, output ):
3326 return main.FALSE
3327 main.log.error( self.name + ": setTestRemove did not" +
3328 " match expected output" )
3329 main.log.debug( self.name + " expected: " + pattern )
3330 main.log.debug( self.name + " actual: " + repr( output ) )
3331 return main.ERROR
3332 except AssertionError:
3333 main.log.error( "Error in processing 'set-test-remove' command: " +
3334 str( output ) )
3335 return main.ERROR
3336 except TypeError:
3337 main.log.exception( self.name + ": Object not as expected" )
3338 return main.ERROR
3339 except pexpect.EOF:
3340 main.log.error( self.name + ": EOF exception found" )
3341 main.log.error( self.name + ": " + self.handle.before )
3342 main.cleanup()
3343 main.exit()
3344 except Exception:
3345 main.log.exception( self.name + ": Uncaught exception!" )
3346 main.cleanup()
3347 main.exit()
3348
3349 def setTestGet( self, setName, values="" ):
3350 """
3351 CLI command to get the elements in a distributed set.
3352 Required arguments:
3353 setName - The name of the set to remove from.
3354 Optional arguments:
3355 values - The value(s) to check if in the set, space seperated.
3356 returns:
3357 main.ERROR on error OR
3358 A list of elements in the set if no optional arguments are
3359 supplied OR
3360 A tuple containing the list then:
3361 main.FALSE if the given values are not in the set OR
3362 main.TRUE if the given values are in the set OR
3363 """
3364 try:
3365 values = str( values ).strip()
3366 setName = str( setName ).strip()
3367 length = len( values.split() )
3368 containsCheck = None
3369 # Patterns to match
3370 setPattern = "\[(.*)\]"
3371 pattern = "Items in set " + setName + ":\n" + setPattern
3372 containsTrue = "Set " + setName + " contains the value " + values
3373 containsFalse = "Set " + setName + " did not contain the value " +\
3374 values
3375 containsAllTrue = "Set " + setName + " contains the the subset " +\
3376 setPattern
3377 containsAllFalse = "Set " + setName + " did not contain the the" +\
3378 " subset " + setPattern
3379
3380 cmdStr = "set-test-get "
3381 cmdStr += setName + " " + values
3382 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003383 try:
3384 # TODO: Maybe make this less hardcoded
3385 # ConsistentMap Exceptions
3386 assert "org.onosproject.store.service" not in output
3387 # Node not leader
3388 assert "java.lang.IllegalStateException" not in output
3389 except AssertionError:
3390 main.log.error( "Error in processing 'set-test-add' " +
3391 "command: " + str( output ) )
3392 retryTime = 30 # Conservative time, given by Madan
3393 main.log.info( "Waiting " + str( retryTime ) +
3394 "seconds before retrying." )
3395 time.sleep( retryTime ) # Due to change in mastership
3396 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003397 assert "Error executing command" not in output
3398 main.log.info( self.name + ": " + output )
3399
3400 if length == 0:
3401 match = re.search( pattern, output )
3402 else: # if given values
3403 if length == 1: # Contains output
3404 patternTrue = pattern + "\n" + containsTrue
3405 patternFalse = pattern + "\n" + containsFalse
3406 else: # ContainsAll output
3407 patternTrue = pattern + "\n" + containsAllTrue
3408 patternFalse = pattern + "\n" + containsAllFalse
3409 matchTrue = re.search( patternTrue, output )
3410 matchFalse = re.search( patternFalse, output )
3411 if matchTrue:
3412 containsCheck = main.TRUE
3413 match = matchTrue
3414 elif matchFalse:
3415 containsCheck = main.FALSE
3416 match = matchFalse
3417 else:
3418 main.log.error( self.name + " setTestGet did not match " +\
3419 "expected output" )
3420 main.log.debug( self.name + " expected: " + pattern )
3421 main.log.debug( self.name + " actual: " + repr( output ) )
3422 match = None
3423 if match:
3424 setMatch = match.group( 1 )
3425 if setMatch == '':
3426 setList = []
3427 else:
3428 setList = setMatch.split( ", " )
3429 if length > 0:
3430 return ( setList, containsCheck )
3431 else:
3432 return setList
3433 else: # no match
3434 main.log.error( self.name + ": setTestGet did not" +
3435 " match expected output" )
3436 main.log.debug( self.name + " expected: " + pattern )
3437 main.log.debug( self.name + " actual: " + repr( output ) )
3438 return main.ERROR
3439 except AssertionError:
3440 main.log.error( "Error in processing 'set-test-get' command: " +
3441 str( output ) )
3442 return main.ERROR
3443 except TypeError:
3444 main.log.exception( self.name + ": Object not as expected" )
3445 return main.ERROR
3446 except pexpect.EOF:
3447 main.log.error( self.name + ": EOF exception found" )
3448 main.log.error( self.name + ": " + self.handle.before )
3449 main.cleanup()
3450 main.exit()
3451 except Exception:
3452 main.log.exception( self.name + ": Uncaught exception!" )
3453 main.cleanup()
3454 main.exit()
3455
3456 def setTestSize( self, setName ):
3457 """
3458 CLI command to get the elements in a distributed set.
3459 Required arguments:
3460 setName - The name of the set to remove from.
3461 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003462 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003463 None on error
3464 """
3465 try:
3466 # TODO: Should this check against the number of elements returned
3467 # and then return true/false based on that?
3468 setName = str( setName ).strip()
3469 # Patterns to match
3470 setPattern = "\[(.*)\]"
3471 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3472 setPattern
3473 cmdStr = "set-test-get -s "
3474 cmdStr += setName
3475 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003476 try:
3477 # TODO: Maybe make this less hardcoded
3478 # ConsistentMap Exceptions
3479 assert "org.onosproject.store.service" not in output
3480 # Node not leader
3481 assert "java.lang.IllegalStateException" not in output
3482 except AssertionError:
3483 main.log.error( "Error in processing 'set-test-add' " +
3484 "command: " + str( output ) )
3485 retryTime = 30 # Conservative time, given by Madan
3486 main.log.info( "Waiting " + str( retryTime ) +
3487 "seconds before retrying." )
3488 time.sleep( retryTime ) # Due to change in mastership
3489 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003490 assert "Error executing command" not in output
3491 main.log.info( self.name + ": " + output )
3492 match = re.search( pattern, output )
3493 if match:
3494 setSize = int( match.group( 1 ) )
3495 setMatch = match.group( 2 )
3496 if len( setMatch.split() ) == setSize:
3497 main.log.info( "The size returned by " + self.name +
3498 " matches the number of elements in " +
3499 "the returned set" )
3500 else:
3501 main.log.error( "The size returned by " + self.name +
3502 " does not match the number of " +
3503 "elements in the returned set." )
3504 return setSize
3505 else: # no match
3506 main.log.error( self.name + ": setTestGet did not" +
3507 " match expected output" )
3508 main.log.debug( self.name + " expected: " + pattern )
3509 main.log.debug( self.name + " actual: " + repr( output ) )
3510 return None
3511 except AssertionError:
3512 main.log.error( "Error in processing 'set-test-get' command: " +
3513 str( output ) )
3514 return None
3515 except TypeError:
3516 main.log.exception( self.name + ": Object not as expected" )
3517 return None
3518 except pexpect.EOF:
3519 main.log.error( self.name + ": EOF exception found" )
3520 main.log.error( self.name + ": " + self.handle.before )
3521 main.cleanup()
3522 main.exit()
3523 except Exception:
3524 main.log.exception( self.name + ": Uncaught exception!" )
3525 main.cleanup()
3526 main.exit()
3527
Jon Hall80daded2015-05-27 16:07:00 -07003528 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003529 """
3530 Command to list the various counters in the system.
3531 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003532 if jsonFormat, a string of the json object returned by the cli
3533 command
3534 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003535 None on error
3536 """
Jon Hall390696c2015-05-05 17:13:41 -07003537 try:
3538 counters = {}
3539 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003540 if jsonFormat:
3541 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003542 output = self.sendline( cmdStr )
3543 assert "Error executing command" not in output
3544 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003545 return output
Jon Hall390696c2015-05-05 17:13:41 -07003546 except AssertionError:
3547 main.log.error( "Error in processing 'counters' command: " +
3548 str( output ) )
Jon Hall80daded2015-05-27 16:07:00 -07003549 return None
Jon Hall390696c2015-05-05 17:13:41 -07003550 except TypeError:
3551 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003552 return None
Jon Hall390696c2015-05-05 17:13:41 -07003553 except pexpect.EOF:
3554 main.log.error( self.name + ": EOF exception found" )
3555 main.log.error( self.name + ": " + self.handle.before )
3556 main.cleanup()
3557 main.exit()
3558 except Exception:
3559 main.log.exception( self.name + ": Uncaught exception!" )
3560 main.cleanup()
3561 main.exit()
3562
3563 def counterTestIncrement( self, counter, inMemory=False ):
3564 """
3565 CLI command to increment and get a distributed counter.
3566 Required arguments:
3567 counter - The name of the counter to increment.
3568 Optional arguments:
3569 inMemory - use in memory map for the counter
3570 returns:
3571 integer value of the counter or
3572 None on Error
3573 """
3574 try:
3575 counter = str( counter )
3576 cmdStr = "counter-test-increment "
3577 if inMemory:
3578 cmdStr += "-i "
3579 cmdStr += counter
3580 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003581 try:
3582 # TODO: Maybe make this less hardcoded
3583 # ConsistentMap Exceptions
3584 assert "org.onosproject.store.service" not in output
3585 # Node not leader
3586 assert "java.lang.IllegalStateException" not in output
3587 except AssertionError:
3588 main.log.error( "Error in processing 'set-test-add' " +
3589 "command: " + str( output ) )
3590 retryTime = 30 # Conservative time, given by Madan
3591 main.log.info( "Waiting " + str( retryTime ) +
3592 "seconds before retrying." )
3593 time.sleep( retryTime ) # Due to change in mastership
3594 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003595 assert "Error executing command" not in output
3596 main.log.info( self.name + ": " + output )
3597 pattern = counter + " was incremented to (\d+)"
3598 match = re.search( pattern, output )
3599 if match:
3600 return int( match.group( 1 ) )
3601 else:
3602 main.log.error( self.name + ": counterTestIncrement did not" +
3603 " match expected output." )
3604 main.log.debug( self.name + " expected: " + pattern )
3605 main.log.debug( self.name + " actual: " + repr( output ) )
3606 return None
3607 except AssertionError:
3608 main.log.error( "Error in processing 'counter-test-increment'" +
3609 " command: " + str( output ) )
3610 return None
3611 except TypeError:
3612 main.log.exception( self.name + ": Object not as expected" )
3613 return None
3614 except pexpect.EOF:
3615 main.log.error( self.name + ": EOF exception found" )
3616 main.log.error( self.name + ": " + self.handle.before )
3617 main.cleanup()
3618 main.exit()
3619 except Exception:
3620 main.log.exception( self.name + ": Uncaught exception!" )
3621 main.cleanup()
3622 main.exit()
3623
kelvin-onlaba297c4d2015-06-01 13:53:55 -07003624 def summary( self, jsonFormat=True ):
3625 """
3626 Description: Execute summary command in onos
3627 Returns: json object ( summary -j ), returns main.FALSE if there is
3628 no output
3629
3630 """
3631 try:
3632 cmdStr = "summary"
3633 if jsonFormat:
3634 cmdStr += " -j"
3635 handle = self.sendline( cmdStr )
3636
3637 if re.search( "Error:", handle ):
3638 main.log.error( self.name + ": summary() response: " +
3639 str( handle ) )
3640 if not handle:
3641 main.log.error( self.name + ": There is no output in " +
3642 "summary command" )
3643 return main.FALSE
3644 return handle
3645 except TypeError:
3646 main.log.exception( self.name + ": Object not as expected" )
3647 return None
3648 except pexpect.EOF:
3649 main.log.error( self.name + ": EOF exception found" )
3650 main.log.error( self.name + ": " + self.handle.before )
3651 main.cleanup()
3652 main.exit()
3653 except Exception:
3654 main.log.exception( self.name + ": Uncaught exception!" )
3655 main.cleanup()
3656 main.exit()