blob: 2c4e68795179df71b021bf4f23fc25888a37a10d [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 pexpect
20import re
Jon Hall30b82fa2015-03-04 17:15:43 -080021import json
22import types
Jon Hallbd16b922015-03-26 17:53:15 -070023import time
kelvin-onlaba4074292015-07-09 15:19:49 -070024import os
andrewonlab95ce8322014-10-13 14:12:04 -040025from drivers.common.clidriver import CLI
26
andrewonlab95ce8322014-10-13 14:12:04 -040027
kelvin8ec71442015-01-15 16:57:00 -080028class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040029
kelvin8ec71442015-01-15 16:57:00 -080030 def __init__( self ):
31 """
32 Initialize client
33 """
Jon Hallefbd9792015-03-05 16:11:36 -080034 self.name = None
35 self.home = None
36 self.handle = None
kelvin8ec71442015-01-15 16:57:00 -080037 super( CLI, self ).__init__()
38
39 def connect( self, **connectargs ):
40 """
andrewonlab95ce8322014-10-13 14:12:04 -040041 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080042 """
andrewonlab95ce8322014-10-13 14:12:04 -040043 try:
44 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080045 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070046 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040047 for key in self.options:
48 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080049 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040050 break
kelvin-onlabfb521662015-02-27 09:52:40 -080051 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070052 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040053
kelvin-onlaba4074292015-07-09 15:19:49 -070054 for key in self.options:
55 if key == 'onosIp':
56 self.onosIp = self.options[ 'onosIp' ]
57 break
58
kelvin8ec71442015-01-15 16:57:00 -080059 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070060
61 try:
Jon Hallc6793552016-01-19 14:18:37 -080062 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070063 self.ip_address = os.getenv( str( self.ip_address ) )
64 else:
65 main.log.info( self.name +
66 ": Trying to connect to " +
67 self.ip_address )
68
69 except KeyError:
70 main.log.info( "Invalid host name," +
71 " connecting to local host instead" )
72 self.ip_address = 'localhost'
73 except Exception as inst:
74 main.log.error( "Uncaught exception: " + str( inst ) )
75
kelvin8ec71442015-01-15 16:57:00 -080076 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080077 user_name=self.user_name,
78 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080079 port=self.port,
80 pwd=self.pwd,
81 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040082
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle.sendline( "cd " + self.home )
84 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040085 if self.handle:
86 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080087 else:
88 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040089 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080090 except TypeError:
91 main.log.exception( self.name + ": Object not as expected" )
92 return None
andrewonlab95ce8322014-10-13 14:12:04 -040093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -080094 main.log.error( self.name + ": EOF exception found" )
95 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -040096 main.cleanup()
97 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -080098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -080099 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400100 main.cleanup()
101 main.exit()
102
kelvin8ec71442015-01-15 16:57:00 -0800103 def disconnect( self ):
104 """
andrewonlab95ce8322014-10-13 14:12:04 -0400105 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800106 """
Jon Halld61331b2015-02-17 16:35:47 -0800107 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400108 try:
Jon Hall61282e32015-03-19 11:34:11 -0700109 if self.handle:
110 i = self.logout()
111 if i == main.TRUE:
112 self.handle.sendline( "" )
113 self.handle.expect( "\$" )
114 self.handle.sendline( "exit" )
115 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800116 except TypeError:
117 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800118 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800120 main.log.error( self.name + ": EOF exception found" )
121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700122 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700123 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700124 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800125 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800126 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400127 response = main.FALSE
128 return response
129
kelvin8ec71442015-01-15 16:57:00 -0800130 def logout( self ):
131 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500132 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700133 Returns main.TRUE if exited CLI and
134 main.FALSE on timeout (not guranteed you are disconnected)
135 None on TypeError
136 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800137 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500138 try:
Jon Hall61282e32015-03-19 11:34:11 -0700139 if self.handle:
140 self.handle.sendline( "" )
141 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
142 timeout=10 )
143 if i == 0: # In ONOS CLI
144 self.handle.sendline( "logout" )
145 self.handle.expect( "\$" )
146 return main.TRUE
147 elif i == 1: # not in CLI
148 return main.TRUE
149 elif i == 3: # Timeout
150 return main.FALSE
151 else:
andrewonlab9627f432014-11-14 12:45:10 -0500152 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800153 except TypeError:
154 main.log.exception( self.name + ": Object not as expected" )
155 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800157 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700158 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500159 main.cleanup()
160 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700161 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700162 main.log.error( self.name +
163 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 main.cleanup()
167 main.exit()
168
kelvin-onlabd3b64892015-01-20 13:26:24 -0800169 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab95ce8322014-10-13 14:12:04 -0400171 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800172
andrewonlab95ce8322014-10-13 14:12:04 -0400173 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800174 """
andrewonlab95ce8322014-10-13 14:12:04 -0400175 try:
176 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800177 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400178 main.cleanup()
179 main.exit()
180 else:
kelvin8ec71442015-01-15 16:57:00 -0800181 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800183 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400184 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800185 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800186 handleBefore = self.handle.before
187 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800188 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800189 self.handle.sendline("")
190 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800191 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 main.log.info( "Cell call returned: " + handleBefore +
194 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400195
196 return main.TRUE
197
Jon Halld4d4b372015-01-28 16:02:41 -0800198 except TypeError:
199 main.log.exception( self.name + ": Object not as expected" )
200 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800202 main.log.error( self.name + ": eof exception found" )
203 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400204 main.cleanup()
205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800207 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400208 main.cleanup()
209 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800210
pingping-lin57a56ce2015-05-20 16:43:48 -0700211 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800212 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800213 """
Jon Hallefbd9792015-03-05 16:11:36 -0800214 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 by user would be used to set the current karaf shell idle timeout.
216 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800217 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 Below is an example to start a session with 60 seconds idle timeout
219 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800220
Hari Krishna25d42f72015-01-05 15:08:28 -0800221 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800222 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800223
kelvin-onlabd3b64892015-01-20 13:26:24 -0800224 Note: karafTimeout is left as str so that this could be read
225 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800226 """
andrewonlab95ce8322014-10-13 14:12:04 -0400227 try:
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.sendline( "" )
229 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700230 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500231
232 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800233 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500234 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400235
kelvin8ec71442015-01-15 16:57:00 -0800236 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800238 i = self.handle.expect( [
239 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700240 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400241
242 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800243 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800244 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800245 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800246 "config:property-set -p org.apache.karaf.shell\
247 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800248 karafTimeout )
249 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800250 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800251 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400252 return main.TRUE
253 else:
kelvin8ec71442015-01-15 16:57:00 -0800254 # If failed, send ctrl+c to process and try again
255 main.log.info( "Starting CLI failed. Retrying..." )
256 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800258 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
259 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400260 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800262 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800263 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800264 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 "config:property-set -p org.apache.karaf.shell\
266 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800267 karafTimeout )
268 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800270 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400271 return main.TRUE
272 else:
kelvin8ec71442015-01-15 16:57:00 -0800273 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400275 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400276
Jon Halld4d4b372015-01-28 16:02:41 -0800277 except TypeError:
278 main.log.exception( self.name + ": Object not as expected" )
279 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400280 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800281 main.log.error( self.name + ": EOF exception found" )
282 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400283 main.cleanup()
284 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800285 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800286 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400287 main.cleanup()
288 main.exit()
289
Jon Hallefbd9792015-03-05 16:11:36 -0800290 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800291 """
292 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800293 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800294 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800295 Available level: DEBUG, TRACE, INFO, WARN, ERROR
296 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800297 """
298 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800299 lvlStr = ""
300 if level:
301 lvlStr = "--level=" + level
302
kelvin-onlab9f541032015-02-04 16:19:53 -0800303 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800304 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700305 if i == 1:
Jon Hallc9eabec2015-06-10 14:33:14 -0700306 main.log.error( self.name + ": onos cli session closed." )
307 main.cleanup()
308 main.exit()
309 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700310 self.handle.sendline( "" )
311 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800312 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700313 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800314 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800315
kelvin-onlab9f541032015-02-04 16:19:53 -0800316 response = self.handle.before
317 if re.search( "Error", response ):
318 return main.FALSE
319 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700320 except pexpect.TIMEOUT:
321 main.log.exception( self.name + ": TIMEOUT exception found" )
322 main.cleanup()
323 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800324 except pexpect.EOF:
325 main.log.error( self.name + ": EOF exception found" )
326 main.log.error( self.name + ": " + self.handle.before )
327 main.cleanup()
328 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800329 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800330 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400331 main.cleanup()
332 main.exit()
333
GlennRCed771242016-01-13 17:02:47 -0800334 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800335 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800336 Send a completely user specified string to
337 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400338 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800339
andrewonlaba18f6bf2014-10-13 19:31:54 -0400340 Warning: There are no sanity checking to commands
341 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800342
kelvin8ec71442015-01-15 16:57:00 -0800343 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400344 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800345 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
346 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800347 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800348 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800349 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800350 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800351 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
352 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700353 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700354 main.log.debug( self.name + ": Raw output" )
355 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700356
357 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800358 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800359 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700360 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700361 main.log.debug( self.name + ": ansiEscape output" )
362 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700363
kelvin-onlabfb521662015-02-27 09:52:40 -0800364 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800365 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700366 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700367 main.log.debug( self.name + ": Removed extra returns " +
368 "from output" )
369 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700370
371 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800372 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700373 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700374 main.log.debug( self.name + ": parsed and stripped output" )
375 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700376
Jon Hall63604932015-02-26 17:09:50 -0800377 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700378 output = response.split( cmdStr.strip(), 1 )
379 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700380 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700381 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800383 output = output[1].strip()
384 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800385 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800386 return output
GlennRCed771242016-01-13 17:02:47 -0800387 except pexpect.TIMEOUT:
388 main.log.error( self.name + ":ONOS timeout" )
389 if debug:
390 main.log.debug( self.handle.before )
391 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700392 except IndexError:
393 main.log.exception( self.name + ": Object not as expected" )
394 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800395 except TypeError:
396 main.log.exception( self.name + ": Object not as expected" )
397 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400398 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800399 main.log.error( self.name + ": EOF exception found" )
400 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400401 main.cleanup()
402 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800403 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800404 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400405 main.cleanup()
406 main.exit()
407
kelvin8ec71442015-01-15 16:57:00 -0800408 # IMPORTANT NOTE:
409 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800410 # the cli command changing 'a:b' with 'aB'.
411 # Ex ) onos:topology > onosTopology
412 # onos:links > onosLinks
413 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800414
kelvin-onlabd3b64892015-01-20 13:26:24 -0800415 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800416 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400417 Adds a new cluster node by ID and address information.
418 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800419 * nodeId
420 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400421 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800422 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800423 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400424 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800425 cmdStr = "add-node " + str( nodeId ) + " " +\
426 str( ONOSIp ) + " " + str( tcpPort )
427 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800428 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800429 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800430 main.log.error( "Error in adding node" )
431 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800432 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400433 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800434 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400435 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800436 except AssertionError:
437 main.log.exception( "" )
438 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800439 except TypeError:
440 main.log.exception( self.name + ": Object not as expected" )
441 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400442 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800443 main.log.error( self.name + ": EOF exception found" )
444 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 main.cleanup()
446 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800447 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800448 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400449 main.cleanup()
450 main.exit()
451
kelvin-onlabd3b64892015-01-20 13:26:24 -0800452 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800453 """
andrewonlab86dc3082014-10-13 18:18:38 -0400454 Removes a cluster by ID
455 Issues command: 'remove-node [<node-id>]'
456 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800457 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800458 """
andrewonlab86dc3082014-10-13 18:18:38 -0400459 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400460
kelvin-onlabd3b64892015-01-20 13:26:24 -0800461 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700462 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800463 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700464 if re.search( "Error", handle ):
465 main.log.error( "Error in removing node" )
466 main.log.error( handle )
467 return main.FALSE
468 else:
469 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800470 except AssertionError:
471 main.log.exception( "" )
472 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800473 except TypeError:
474 main.log.exception( self.name + ": Object not as expected" )
475 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800477 main.log.error( self.name + ": EOF exception found" )
478 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400479 main.cleanup()
480 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800481 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800482 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400483 main.cleanup()
484 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400485
Jon Hall61282e32015-03-19 11:34:11 -0700486 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800487 """
andrewonlab7c211572014-10-15 16:45:20 -0400488 List the nodes currently visible
489 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700490 Optional argument:
491 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800492 """
andrewonlab7c211572014-10-15 16:45:20 -0400493 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700494 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700495 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700496 cmdStr += " -j"
497 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800498 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700499 return output
Jon Hallc6793552016-01-19 14:18:37 -0800500 except AssertionError:
501 main.log.exception( "" )
502 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800503 except TypeError:
504 main.log.exception( self.name + ": Object not as expected" )
505 return None
andrewonlab7c211572014-10-15 16:45:20 -0400506 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800507 main.log.error( self.name + ": EOF exception found" )
508 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400509 main.cleanup()
510 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800511 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800512 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400513 main.cleanup()
514 main.exit()
515
kelvin8ec71442015-01-15 16:57:00 -0800516 def topology( self ):
517 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700518 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700519 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700520 Return:
521 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800522 """
andrewonlab95ce8322014-10-13 14:12:04 -0400523 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700524 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800525 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800526 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700527 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400528 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800529 except AssertionError:
530 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800531 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800532 except TypeError:
533 main.log.exception( self.name + ": Object not as expected" )
534 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400535 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800536 main.log.error( self.name + ": EOF exception found" )
537 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400538 main.cleanup()
539 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800540 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800541 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400542 main.cleanup()
543 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800544
jenkins7ead5a82015-03-13 10:28:21 -0700545 def deviceRemove( self, deviceId ):
546 """
547 Removes particular device from storage
548
549 TODO: refactor this function
550 """
551 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700552 cmdStr = "device-remove " + str( deviceId )
553 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800554 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700555 if re.search( "Error", handle ):
556 main.log.error( "Error in removing device" )
557 main.log.error( handle )
558 return main.FALSE
559 else:
560 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800561 except AssertionError:
562 main.log.exception( "" )
563 return None
jenkins7ead5a82015-03-13 10:28:21 -0700564 except TypeError:
565 main.log.exception( self.name + ": Object not as expected" )
566 return None
567 except pexpect.EOF:
568 main.log.error( self.name + ": EOF exception found" )
569 main.log.error( self.name + ": " + self.handle.before )
570 main.cleanup()
571 main.exit()
572 except Exception:
573 main.log.exception( self.name + ": Uncaught exception!" )
574 main.cleanup()
575 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700576
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800578 """
Jon Hall7b02d952014-10-17 20:14:54 -0400579 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400580 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800582 """
andrewonlab86dc3082014-10-13 18:18:38 -0400583 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700584 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700586 cmdStr += " -j"
587 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800588 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700589 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800590 except AssertionError:
591 main.log.exception( "" )
592 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800593 except TypeError:
594 main.log.exception( self.name + ": Object not as expected" )
595 return None
andrewonlab7c211572014-10-15 16:45:20 -0400596 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800597 main.log.error( self.name + ": EOF exception found" )
598 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400599 main.cleanup()
600 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800601 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800602 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400603 main.cleanup()
604 main.exit()
605
kelvin-onlabd3b64892015-01-20 13:26:24 -0800606 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800607 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800608 This balances the devices across all controllers
609 by issuing command: 'onos> onos:balance-masters'
610 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800611 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800612 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800613 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700614 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800615 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700616 if re.search( "Error", handle ):
617 main.log.error( "Error in balancing masters" )
618 main.log.error( handle )
619 return main.FALSE
620 else:
621 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800622 except AssertionError:
623 main.log.exception( "" )
624 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800625 except TypeError:
626 main.log.exception( self.name + ": Object not as expected" )
627 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800628 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800629 main.log.error( self.name + ": EOF exception found" )
630 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800631 main.cleanup()
632 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800633 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800634 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800635 main.cleanup()
636 main.exit()
637
Jon Hallc6793552016-01-19 14:18:37 -0800638 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700639 """
640 Returns the output of the masters command.
641 Optional argument:
642 * jsonFormat - boolean indicating if you want output in json
643 """
644 try:
645 cmdStr = "onos:masters"
646 if jsonFormat:
647 cmdStr += " -j"
648 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800649 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700650 return output
Jon Hallc6793552016-01-19 14:18:37 -0800651 except AssertionError:
652 main.log.exception( "" )
653 return None
acsmars24950022015-07-30 18:00:43 -0700654 except TypeError:
655 main.log.exception( self.name + ": Object not as expected" )
656 return None
657 except pexpect.EOF:
658 main.log.error( self.name + ": EOF exception found" )
659 main.log.error( self.name + ": " + self.handle.before )
660 main.cleanup()
661 main.exit()
662 except Exception:
663 main.log.exception( self.name + ": Uncaught exception!" )
664 main.cleanup()
665 main.exit()
666
Jon Hallc6793552016-01-19 14:18:37 -0800667 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700668 """
669 Uses the master command to check that the devices' leadership
670 is evenly divided
671
672 Dependencies: checkMasters() and summary()
673
674 Returns main.True if the devices are balanced
675 Returns main.False if the devices are unbalanced
676 Exits on Exception
677 Returns None on TypeError
678 """
679 try:
Jon Hallc6793552016-01-19 14:18:37 -0800680 summaryOutput = self.summary()
681 totalDevices = json.loads( summaryOutput )[ "devices" ]
682 except ( TypeError, ValueError ):
683 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
684 return None
685 try:
acsmars24950022015-07-30 18:00:43 -0700686 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800687 mastersOutput = self.checkMasters()
688 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700689 first = masters[ 0 ][ "size" ]
690 for master in masters:
691 totalOwnedDevices += master[ "size" ]
692 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
693 main.log.error( "Mastership not balanced" )
694 main.log.info( "\n" + self.checkMasters( False ) )
695 return main.FALSE
696 main.log.info( "Mastership balanced between " \
697 + str( len(masters) ) + " masters" )
698 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800699 except ( TypeError, ValueError ):
700 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700701 return None
702 except pexpect.EOF:
703 main.log.error( self.name + ": EOF exception found" )
704 main.log.error( self.name + ": " + self.handle.before )
705 main.cleanup()
706 main.exit()
707 except Exception:
708 main.log.exception( self.name + ": Uncaught exception!" )
709 main.cleanup()
710 main.exit()
711
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800713 """
Jon Halle8217482014-10-17 13:49:14 -0400714 Lists all core links
715 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800716 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800717 """
Jon Halle8217482014-10-17 13:49:14 -0400718 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800720 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700721 cmdStr += " -j"
722 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800723 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700724 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
Jon Halle8217482014-10-17 13:49:14 -0400731 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400734 main.cleanup()
735 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800736 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800737 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400738 main.cleanup()
739 main.exit()
740
kelvin-onlabd3b64892015-01-20 13:26:24 -0800741 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800742 """
Jon Halle8217482014-10-17 13:49:14 -0400743 Lists all ports
744 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800746 """
Jon Halle8217482014-10-17 13:49:14 -0400747 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700750 cmdStr += " -j"
751 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800752 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800754 except AssertionError:
755 main.log.exception( "" )
756 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800757 except TypeError:
758 main.log.exception( self.name + ": Object not as expected" )
759 return None
Jon Halle8217482014-10-17 13:49:14 -0400760 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400763 main.cleanup()
764 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800765 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800766 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400767 main.cleanup()
768 main.exit()
769
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800771 """
Jon Hall983a1702014-10-28 18:44:22 -0400772 Lists all devices and the controllers with roles assigned to them
773 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800775 """
andrewonlab7c211572014-10-15 16:45:20 -0400776 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800778 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr += " -j"
780 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800781 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700782 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800783 except AssertionError:
784 main.log.exception( "" )
785 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800786 except TypeError:
787 main.log.exception( self.name + ": Object not as expected" )
788 return None
Jon Hall983a1702014-10-28 18:44:22 -0400789 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800790 main.log.error( self.name + ": EOF exception found" )
791 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400792 main.cleanup()
793 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400796 main.cleanup()
797 main.exit()
798
kelvin-onlabd3b64892015-01-20 13:26:24 -0800799 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800800 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800801 Given the a string containing the json representation of the "roles"
802 cli command and a partial or whole device id, returns a json object
803 containing the roles output for the first device whose id contains
804 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400805
806 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800807 A dict of the role assignments for the given device or
808 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800809 """
Jon Hall983a1702014-10-28 18:44:22 -0400810 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400812 return None
813 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800814 rawRoles = self.roles()
815 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800816 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800817 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800818 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800819 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400820 return device
821 return None
Jon Hallc6793552016-01-19 14:18:37 -0800822 except ( TypeError, ValueError ):
823 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800824 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400825 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800826 main.log.error( self.name + ": EOF exception found" )
827 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400828 main.cleanup()
829 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800830 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800831 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400832 main.cleanup()
833 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800834
kelvin-onlabd3b64892015-01-20 13:26:24 -0800835 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800836 """
Jon Hall94fd0472014-12-08 11:52:42 -0800837 Iterates through each device and checks if there is a master assigned
838 Returns: main.TRUE if each device has a master
839 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800840 """
Jon Hall94fd0472014-12-08 11:52:42 -0800841 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800842 rawRoles = self.roles()
843 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800844 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800845 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800846 # print device
847 if device[ 'master' ] == "none":
848 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800849 return main.FALSE
850 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800851 except ( TypeError, ValueError ):
852 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800853 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800854 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800857 main.cleanup()
858 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800859 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800860 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800861 main.cleanup()
862 main.exit()
863
kelvin-onlabd3b64892015-01-20 13:26:24 -0800864 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800865 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400866 Returns string of paths, and the cost.
867 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800868 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400869 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800870 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
871 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800872 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800873 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800874 main.log.error( "Error in getting paths" )
875 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400876 else:
kelvin8ec71442015-01-15 16:57:00 -0800877 path = handle.split( ";" )[ 0 ]
878 cost = handle.split( ";" )[ 1 ]
879 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800880 except AssertionError:
881 main.log.exception( "" )
882 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800883 except TypeError:
884 main.log.exception( self.name + ": Object not as expected" )
885 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400886 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800887 main.log.error( self.name + ": EOF exception found" )
888 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400889 main.cleanup()
890 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800891 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800892 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400893 main.cleanup()
894 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800897 """
Jon Hallffb386d2014-11-21 13:43:38 -0800898 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400899 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400902 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700905 cmdStr += " -j"
906 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800907 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800908 try:
909 # TODO: Maybe make this less hardcoded
910 # ConsistentMap Exceptions
911 assert "org.onosproject.store.service" not in handle
912 # Node not leader
913 assert "java.lang.IllegalStateException" not in handle
914 except AssertionError:
915 main.log.error( "Error in processing '" + cmdStr + "' " +
916 "command: " + str( handle ) )
917 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700918 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800919 except AssertionError:
920 main.log.exception( "" )
921 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800922 except TypeError:
923 main.log.exception( self.name + ": Object not as expected" )
924 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800926 main.log.error( self.name + ": EOF exception found" )
927 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400928 main.cleanup()
929 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800930 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800931 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400932 main.cleanup()
933 main.exit()
934
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800936 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400937 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800938
Jon Hallefbd9792015-03-05 16:11:36 -0800939 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800940 partial mac address
941
Jon Hall42db6dc2014-10-24 19:03:48 -0400942 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800943 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400944 try:
kelvin8ec71442015-01-15 16:57:00 -0800945 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400946 return None
947 else:
948 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 rawHosts = self.hosts()
950 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800951 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800953 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800954 if not host:
955 pass
956 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400957 return host
958 return None
Jon Hallc6793552016-01-19 14:18:37 -0800959 except ( TypeError, ValueError ):
960 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800961 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800963 main.log.error( self.name + ": EOF exception found" )
964 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400965 main.cleanup()
966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800968 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400969 main.cleanup()
970 main.exit()
971
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800973 """
974 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400975 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800976
andrewonlab3f0a4af2014-10-17 12:25:14 -0400977 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800978 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -0400979 IMPORTANT:
980 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -0800981 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -0400982 Furthermore, it assumes that value of VLAN is '-1'
983 Description:
kelvin8ec71442015-01-15 16:57:00 -0800984 Converts mininet hosts ( h1, h2, h3... ) into
985 ONOS format ( 00:00:00:00:00:01/-1 , ... )
986 """
andrewonlab3f0a4af2014-10-17 12:25:14 -0400987 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -0400989
kelvin-onlabd3b64892015-01-20 13:26:24 -0800990 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -0800991 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 hostHex = hex( int( host ) ).zfill( 12 )
993 hostHex = str( hostHex ).replace( 'x', '0' )
994 i = iter( str( hostHex ) )
995 hostHex = ":".join( a + b for a, b in zip( i, i ) )
996 hostHex = hostHex + "/-1"
997 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000
Jon Halld4d4b372015-01-28 16:02:41 -08001001 except TypeError:
1002 main.log.exception( self.name + ": Object not as expected" )
1003 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001004 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001005 main.log.error( self.name + ": EOF exception found" )
1006 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001007 main.cleanup()
1008 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001011 main.cleanup()
1012 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlabe6745342014-10-17 14:29:13 -04001016 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 * hostIdOne: ONOS host id for host1
1018 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001019 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001020 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001021 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001022 Returns:
1023 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001024 """
andrewonlabe6745342014-10-17 14:29:13 -04001025 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1027 " " + str( hostIdTwo )
1028 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001029 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001030 if re.search( "Error", handle ):
1031 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001032 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001033 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001034 else:
1035 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001036 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1037 match = re.search('id=0x([\da-f]+),', handle)
1038 if match:
1039 return match.group()[3:-1]
1040 else:
1041 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001042 main.log.debug( "Response from ONOS was: " +
1043 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001044 return None
Jon Hallc6793552016-01-19 14:18:37 -08001045 except AssertionError:
1046 main.log.exception( "" )
1047 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001048 except TypeError:
1049 main.log.exception( self.name + ": Object not as expected" )
1050 return None
andrewonlabe6745342014-10-17 14:29:13 -04001051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001052 main.log.error( self.name + ": EOF exception found" )
1053 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001054 main.cleanup()
1055 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001056 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001057 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001058 main.cleanup()
1059 main.exit()
1060
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001062 """
andrewonlab7b31d232014-10-24 13:31:47 -04001063 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 * ingressDevice: device id of ingress device
1065 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001066 Optional:
1067 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001068 Description:
1069 Adds an optical intent by specifying an ingress and egress device
1070 Returns:
1071 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001072 """
andrewonlab7b31d232014-10-24 13:31:47 -04001073 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1075 " " + str( egressDevice )
1076 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001077 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001078 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001079 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001080 main.log.error( "Error in adding Optical intent" )
1081 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001082 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001083 main.log.info( "Optical intent installed between " +
1084 str( ingressDevice ) + " and " +
1085 str( egressDevice ) )
1086 match = re.search('id=0x([\da-f]+),', handle)
1087 if match:
1088 return match.group()[3:-1]
1089 else:
1090 main.log.error( "Error, intent ID not found" )
1091 return None
Jon Hallc6793552016-01-19 14:18:37 -08001092 except AssertionError:
1093 main.log.exception( "" )
1094 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001095 except TypeError:
1096 main.log.exception( self.name + ": Object not as expected" )
1097 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001098 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001099 main.log.error( self.name + ": EOF exception found" )
1100 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001101 main.cleanup()
1102 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001103 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001104 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001105 main.cleanup()
1106 main.exit()
1107
kelvin-onlabd3b64892015-01-20 13:26:24 -08001108 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001109 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 ingressDevice,
1111 egressDevice,
1112 portIngress="",
1113 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001114 ethType="",
1115 ethSrc="",
1116 ethDst="",
1117 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001119 ipProto="",
1120 ipSrc="",
1121 ipDst="",
1122 tcpSrc="",
1123 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001124 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001125 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 * ingressDevice: device id of ingress device
1127 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001128 Optional:
1129 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001130 * ethSrc: specify ethSrc ( i.e. src mac addr )
1131 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001132 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001134 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001135 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001136 * ipSrc: specify ip source address
1137 * ipDst: specify ip destination address
1138 * tcpSrc: specify tcp source port
1139 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001140 Description:
kelvin8ec71442015-01-15 16:57:00 -08001141 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001142 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001143 Returns:
1144 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001145
Jon Halle3f39ff2015-01-13 11:50:53 -08001146 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001147 options developers provide for point-to-point
1148 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001149 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001150 try:
kelvin8ec71442015-01-15 16:57:00 -08001151 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001152 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001154 and not ipProto and not ipSrc and not ipDst \
1155 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001156 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001157
andrewonlab289e4b72014-10-21 21:24:18 -04001158 else:
andrewonlab36af3822014-11-18 17:48:18 -05001159 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001160
andrewonlab0c0a6772014-10-22 12:31:18 -04001161 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001162 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001163 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001164 cmd += " --ethSrc " + str( ethSrc )
1165 if ethDst:
1166 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001167 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001168 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001170 cmd += " --lambda "
1171 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001172 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001173 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001174 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001175 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001176 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001177 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001178 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001179 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001180 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001181
kelvin8ec71442015-01-15 16:57:00 -08001182 # Check whether the user appended the port
1183 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 if "/" in ingressDevice:
1185 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001186 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001187 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001189 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001190 # Would it make sense to throw an exception and exit
1191 # the test?
1192 return None
andrewonlab36af3822014-11-18 17:48:18 -05001193
kelvin8ec71442015-01-15 16:57:00 -08001194 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 str( ingressDevice ) + "/" +\
1196 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001197
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 if "/" in egressDevice:
1199 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001200 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001202 main.log.error( "You must specify the egress port" )
1203 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001204
kelvin8ec71442015-01-15 16:57:00 -08001205 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 str( egressDevice ) + "/" +\
1207 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001208
kelvin-onlab898a6c62015-01-16 14:13:53 -08001209 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001210 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001211 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001212 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001213 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001215 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001216 # TODO: print out all the options in this message?
1217 main.log.info( "Point-to-point intent installed between " +
1218 str( ingressDevice ) + " and " +
1219 str( egressDevice ) )
1220 match = re.search('id=0x([\da-f]+),', handle)
1221 if match:
1222 return match.group()[3:-1]
1223 else:
1224 main.log.error( "Error, intent ID not found" )
1225 return None
Jon Hallc6793552016-01-19 14:18:37 -08001226 except AssertionError:
1227 main.log.exception( "" )
1228 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001229 except TypeError:
1230 main.log.exception( self.name + ": Object not as expected" )
1231 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001232 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001233 main.log.error( self.name + ": EOF exception found" )
1234 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001235 main.cleanup()
1236 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001238 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001239 main.cleanup()
1240 main.exit()
1241
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001243 self,
shahshreyac2f97072015-03-19 17:04:29 -07001244 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001246 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001247 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001248 ethType="",
1249 ethSrc="",
1250 ethDst="",
1251 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001253 ipProto="",
1254 ipSrc="",
1255 ipDst="",
1256 tcpSrc="",
1257 tcpDst="",
1258 setEthSrc="",
1259 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001260 """
shahshreyad0c80432014-12-04 16:56:05 -08001261 Note:
shahshreya70622b12015-03-19 17:19:00 -07001262 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001263 is same. That is, all ingress devices include port numbers
1264 with a "/" or all ingress devices could specify device
1265 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001266 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001267 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001268 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001270 Optional:
1271 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001272 * ethSrc: specify ethSrc ( i.e. src mac addr )
1273 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001274 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001275 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001276 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001277 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001278 * ipSrc: specify ip source address
1279 * ipDst: specify ip destination address
1280 * tcpSrc: specify tcp source port
1281 * tcpDst: specify tcp destination port
1282 * setEthSrc: action to Rewrite Source MAC Address
1283 * setEthDst: action to Rewrite Destination MAC Address
1284 Description:
kelvin8ec71442015-01-15 16:57:00 -08001285 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001286 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001287 Returns:
1288 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001289
Jon Halle3f39ff2015-01-13 11:50:53 -08001290 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001291 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001292 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001293 """
shahshreyad0c80432014-12-04 16:56:05 -08001294 try:
kelvin8ec71442015-01-15 16:57:00 -08001295 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001296 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001298 and not ipProto and not ipSrc and not ipDst\
1299 and not tcpSrc and not tcpDst and not setEthSrc\
1300 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001301 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001302
1303 else:
1304 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001305
shahshreyad0c80432014-12-04 16:56:05 -08001306 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001307 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001308 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001309 cmd += " --ethSrc " + str( ethSrc )
1310 if ethDst:
1311 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001312 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001313 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001315 cmd += " --lambda "
1316 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001317 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001318 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001319 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001320 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001321 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001322 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001323 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001324 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001325 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001326 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001327 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001328 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001329 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001330
kelvin8ec71442015-01-15 16:57:00 -08001331 # Check whether the user appended the port
1332 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001333
1334 if portIngressList is None:
1335 for ingressDevice in ingressDeviceList:
1336 if "/" in ingressDevice:
1337 cmd += " " + str( ingressDevice )
1338 else:
1339 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001340 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001341 # TODO: perhaps more meaningful return
1342 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001343 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001344 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001345 for ingressDevice, portIngress in zip( ingressDeviceList,
1346 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001347 cmd += " " + \
1348 str( ingressDevice ) + "/" +\
1349 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001350 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001351 main.log.error( "Device list and port list does not " +
1352 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001353 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 if "/" in egressDevice:
1355 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001356 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001358 main.log.error( "You must specify " +
1359 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001360 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001361
kelvin8ec71442015-01-15 16:57:00 -08001362 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 str( egressDevice ) + "/" +\
1364 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001366 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001367 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001368 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001369 main.log.error( "Error in adding multipoint-to-singlepoint " +
1370 "intent" )
1371 return None
shahshreyad0c80432014-12-04 16:56:05 -08001372 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001373 match = re.search('id=0x([\da-f]+),', handle)
1374 if match:
1375 return match.group()[3:-1]
1376 else:
1377 main.log.error( "Error, intent ID not found" )
1378 return None
Jon Hallc6793552016-01-19 14:18:37 -08001379 except AssertionError:
1380 main.log.exception( "" )
1381 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001382 except TypeError:
1383 main.log.exception( self.name + ": Object not as expected" )
1384 return None
1385 except pexpect.EOF:
1386 main.log.error( self.name + ": EOF exception found" )
1387 main.log.error( self.name + ": " + self.handle.before )
1388 main.cleanup()
1389 main.exit()
1390 except Exception:
1391 main.log.exception( self.name + ": Uncaught exception!" )
1392 main.cleanup()
1393 main.exit()
1394
1395 def addSinglepointToMultipointIntent(
1396 self,
1397 ingressDevice,
1398 egressDeviceList,
1399 portIngress="",
1400 portEgressList=None,
1401 ethType="",
1402 ethSrc="",
1403 ethDst="",
1404 bandwidth="",
1405 lambdaAlloc=False,
1406 ipProto="",
1407 ipSrc="",
1408 ipDst="",
1409 tcpSrc="",
1410 tcpDst="",
1411 setEthSrc="",
1412 setEthDst="" ):
1413 """
1414 Note:
1415 This function assumes the format of all egress devices
1416 is same. That is, all egress devices include port numbers
1417 with a "/" or all egress devices could specify device
1418 ids and port numbers seperately.
1419 Required:
1420 * EgressDeviceList: List of device ids of egress device
1421 ( Atleast 2 eress devices required in the list )
1422 * ingressDevice: device id of ingress device
1423 Optional:
1424 * ethType: specify ethType
1425 * ethSrc: specify ethSrc ( i.e. src mac addr )
1426 * ethDst: specify ethDst ( i.e. dst mac addr )
1427 * bandwidth: specify bandwidth capacity of link
1428 * lambdaAlloc: if True, intent will allocate lambda
1429 for the specified intent
1430 * ipProto: specify ip protocol
1431 * ipSrc: specify ip source address
1432 * ipDst: specify ip destination address
1433 * tcpSrc: specify tcp source port
1434 * tcpDst: specify tcp destination port
1435 * setEthSrc: action to Rewrite Source MAC Address
1436 * setEthDst: action to Rewrite Destination MAC Address
1437 Description:
1438 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1439 specifying device id's and optional fields
1440 Returns:
1441 A string of the intent id or None on error
1442
1443 NOTE: This function may change depending on the
1444 options developers provide for singlepoint-to-multipoint
1445 intent via cli
1446 """
1447 try:
1448 # If there are no optional arguments
1449 if not ethType and not ethSrc and not ethDst\
1450 and not bandwidth and not lambdaAlloc\
1451 and not ipProto and not ipSrc and not ipDst\
1452 and not tcpSrc and not tcpDst and not setEthSrc\
1453 and not setEthDst:
1454 cmd = "add-single-to-multi-intent"
1455
1456 else:
1457 cmd = "add-single-to-multi-intent"
1458
1459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483
1484 # Check whether the user appended the port
1485 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001486
kelvin-onlabb9408212015-04-01 13:34:04 -07001487 if "/" in ingressDevice:
1488 cmd += " " + str( ingressDevice )
1489 else:
1490 if not portIngress:
1491 main.log.error( "You must specify " +
1492 "the Ingress port" )
1493 return main.FALSE
1494
1495 cmd += " " +\
1496 str( ingressDevice ) + "/" +\
1497 str( portIngress )
1498
1499 if portEgressList is None:
1500 for egressDevice in egressDeviceList:
1501 if "/" in egressDevice:
1502 cmd += " " + str( egressDevice )
1503 else:
1504 main.log.error( "You must specify " +
1505 "the egress port" )
1506 # TODO: perhaps more meaningful return
1507 return main.FALSE
1508 else:
1509 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001510 for egressDevice, portEgress in zip( egressDeviceList,
1511 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001512 cmd += " " + \
1513 str( egressDevice ) + "/" +\
1514 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001515 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001516 main.log.error( "Device list and port list does not " +
1517 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001518 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001519 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001520 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001521 # If error, return error message
1522 if re.search( "Error", handle ):
1523 main.log.error( "Error in adding singlepoint-to-multipoint " +
1524 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001525 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001526 else:
1527 match = re.search('id=0x([\da-f]+),', handle)
1528 if match:
1529 return match.group()[3:-1]
1530 else:
1531 main.log.error( "Error, intent ID not found" )
1532 return None
Jon Hallc6793552016-01-19 14:18:37 -08001533 except AssertionError:
1534 main.log.exception( "" )
1535 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001536 except TypeError:
1537 main.log.exception( self.name + ": Object not as expected" )
1538 return None
shahshreyad0c80432014-12-04 16:56:05 -08001539 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001540 main.log.error( self.name + ": EOF exception found" )
1541 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001542 main.cleanup()
1543 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001544 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001545 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001546 main.cleanup()
1547 main.exit()
1548
Hari Krishna9e232602015-04-13 17:29:08 -07001549 def addMplsIntent(
1550 self,
1551 ingressDevice,
1552 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001553 ingressPort="",
1554 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001555 ethType="",
1556 ethSrc="",
1557 ethDst="",
1558 bandwidth="",
1559 lambdaAlloc=False,
1560 ipProto="",
1561 ipSrc="",
1562 ipDst="",
1563 tcpSrc="",
1564 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001565 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001566 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001567 priority=""):
1568 """
1569 Required:
1570 * ingressDevice: device id of ingress device
1571 * egressDevice: device id of egress device
1572 Optional:
1573 * ethType: specify ethType
1574 * ethSrc: specify ethSrc ( i.e. src mac addr )
1575 * ethDst: specify ethDst ( i.e. dst mac addr )
1576 * bandwidth: specify bandwidth capacity of link
1577 * lambdaAlloc: if True, intent will allocate lambda
1578 for the specified intent
1579 * ipProto: specify ip protocol
1580 * ipSrc: specify ip source address
1581 * ipDst: specify ip destination address
1582 * tcpSrc: specify tcp source port
1583 * tcpDst: specify tcp destination port
1584 * ingressLabel: Ingress MPLS label
1585 * egressLabel: Egress MPLS label
1586 Description:
1587 Adds MPLS intent by
1588 specifying device id's and optional fields
1589 Returns:
1590 A string of the intent id or None on error
1591
1592 NOTE: This function may change depending on the
1593 options developers provide for MPLS
1594 intent via cli
1595 """
1596 try:
1597 # If there are no optional arguments
1598 if not ethType and not ethSrc and not ethDst\
1599 and not bandwidth and not lambdaAlloc \
1600 and not ipProto and not ipSrc and not ipDst \
1601 and not tcpSrc and not tcpDst and not ingressLabel \
1602 and not egressLabel:
1603 cmd = "add-mpls-intent"
1604
1605 else:
1606 cmd = "add-mpls-intent"
1607
1608 if ethType:
1609 cmd += " --ethType " + str( ethType )
1610 if ethSrc:
1611 cmd += " --ethSrc " + str( ethSrc )
1612 if ethDst:
1613 cmd += " --ethDst " + str( ethDst )
1614 if bandwidth:
1615 cmd += " --bandwidth " + str( bandwidth )
1616 if lambdaAlloc:
1617 cmd += " --lambda "
1618 if ipProto:
1619 cmd += " --ipProto " + str( ipProto )
1620 if ipSrc:
1621 cmd += " --ipSrc " + str( ipSrc )
1622 if ipDst:
1623 cmd += " --ipDst " + str( ipDst )
1624 if tcpSrc:
1625 cmd += " --tcpSrc " + str( tcpSrc )
1626 if tcpDst:
1627 cmd += " --tcpDst " + str( tcpDst )
1628 if ingressLabel:
1629 cmd += " --ingressLabel " + str( ingressLabel )
1630 if egressLabel:
1631 cmd += " --egressLabel " + str( egressLabel )
1632 if priority:
1633 cmd += " --priority " + str( priority )
1634
1635 # Check whether the user appended the port
1636 # or provided it as an input
1637 if "/" in ingressDevice:
1638 cmd += " " + str( ingressDevice )
1639 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001640 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001641 main.log.error( "You must specify the ingress port" )
1642 return None
1643
1644 cmd += " " + \
1645 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001646 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001647
1648 if "/" in egressDevice:
1649 cmd += " " + str( egressDevice )
1650 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001651 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001652 main.log.error( "You must specify the egress port" )
1653 return None
1654
1655 cmd += " " +\
1656 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001657 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001658
1659 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001660 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001661 # If error, return error message
1662 if re.search( "Error", handle ):
1663 main.log.error( "Error in adding mpls intent" )
1664 return None
1665 else:
1666 # TODO: print out all the options in this message?
1667 main.log.info( "MPLS intent installed between " +
1668 str( ingressDevice ) + " and " +
1669 str( egressDevice ) )
1670 match = re.search('id=0x([\da-f]+),', handle)
1671 if match:
1672 return match.group()[3:-1]
1673 else:
1674 main.log.error( "Error, intent ID not found" )
1675 return None
Jon Hallc6793552016-01-19 14:18:37 -08001676 except AssertionError:
1677 main.log.exception( "" )
1678 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001679 except TypeError:
1680 main.log.exception( self.name + ": Object not as expected" )
1681 return None
1682 except pexpect.EOF:
1683 main.log.error( self.name + ": EOF exception found" )
1684 main.log.error( self.name + ": " + self.handle.before )
1685 main.cleanup()
1686 main.exit()
1687 except Exception:
1688 main.log.exception( self.name + ": Uncaught exception!" )
1689 main.cleanup()
1690 main.exit()
1691
Jon Hallefbd9792015-03-05 16:11:36 -08001692 def removeIntent( self, intentId, app='org.onosproject.cli',
1693 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001694 """
shahshreya1c818fc2015-02-26 13:44:08 -08001695 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001696 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001697 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001698 -p or --purge: Purge the intent from the store after removal
1699
Jon Halle3f39ff2015-01-13 11:50:53 -08001700 Returns:
1701 main.False on error and
1702 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001703 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001704 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001705 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001706 if purge:
1707 cmdStr += " -p"
1708 if sync:
1709 cmdStr += " -s"
1710
1711 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001712 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001713 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001714 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001715 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001716 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001717 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001718 # TODO: Should this be main.TRUE
1719 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001720 except AssertionError:
1721 main.log.exception( "" )
1722 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001723 except TypeError:
1724 main.log.exception( self.name + ": Object not as expected" )
1725 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001726 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001727 main.log.error( self.name + ": EOF exception found" )
1728 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001729 main.cleanup()
1730 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001731 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001732 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001733 main.cleanup()
1734 main.exit()
1735
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001736 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001737 """
1738 Purges all WITHDRAWN Intents
1739 """
1740 try:
1741 cmdStr = "purge-intents"
1742 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001743 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001744 if re.search( "Error", handle ):
1745 main.log.error( "Error in purging intents" )
1746 return main.FALSE
1747 else:
1748 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001749 except AssertionError:
1750 main.log.exception( "" )
1751 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001752 except TypeError:
1753 main.log.exception( self.name + ": Object not as expected" )
1754 return None
1755 except pexpect.EOF:
1756 main.log.error( self.name + ": EOF exception found" )
1757 main.log.error( self.name + ": " + self.handle.before )
1758 main.cleanup()
1759 main.exit()
1760 except Exception:
1761 main.log.exception( self.name + ": Uncaught exception!" )
1762 main.cleanup()
1763 main.exit()
1764
kelvin-onlabd3b64892015-01-20 13:26:24 -08001765 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001766 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001767 NOTE: This method should be used after installing application:
1768 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001769 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001770 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001771 Description:
1772 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001773 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001774 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001775 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001776 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001777 cmdStr += " -j"
1778 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001779 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001780 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001781 except AssertionError:
1782 main.log.exception( "" )
1783 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001784 except TypeError:
1785 main.log.exception( self.name + ": Object not as expected" )
1786 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001788 main.log.error( self.name + ": EOF exception found" )
1789 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001790 main.cleanup()
1791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001793 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001794 main.cleanup()
1795 main.exit()
1796
pingping-lin54b03372015-08-13 14:43:10 -07001797 def ipv4RouteNumber( self ):
1798 """
1799 NOTE: This method should be used after installing application:
1800 onos-app-sdnip
1801 Description:
1802 Obtain the total IPv4 routes number in the system
1803 """
1804 try:
1805 cmdStr = "routes -s -j"
1806 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001807 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001808 jsonResult = json.loads( handle )
1809 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001810 except AssertionError:
1811 main.log.exception( "" )
1812 return None
1813 except ( TypeError, ValueError ):
1814 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001815 return None
1816 except pexpect.EOF:
1817 main.log.error( self.name + ": EOF exception found" )
1818 main.log.error( self.name + ": " + self.handle.before )
1819 main.cleanup()
1820 main.exit()
1821 except Exception:
1822 main.log.exception( self.name + ": Uncaught exception!" )
1823 main.cleanup()
1824 main.exit()
1825
pingping-lin8244a3b2015-09-16 13:36:56 -07001826 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001827 """
andrewonlabe6745342014-10-17 14:29:13 -04001828 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001829 Obtain intents from the ONOS cli.
1830 Optional:
1831 * jsonFormat: Enable output formatting in json, default to True
1832 * summary: Whether only output the intent summary, defaults to False
1833 * type: Only output a certain type of intent. This options is valid
1834 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001835 """
andrewonlabe6745342014-10-17 14:29:13 -04001836 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001837 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001838 if summary:
1839 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001840 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001841 cmdStr += " -j"
1842 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001843 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001844 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001845 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001846 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001847 else:
Jon Hallff566d52016-01-15 14:45:36 -08001848 intentType = ""
1849 # IF we want the summary of a specific intent type
1850 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001851 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001852 if intentType in jsonResult.keys():
1853 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001854 else:
Jon Hallff566d52016-01-15 14:45:36 -08001855 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001856 return handle
1857 else:
Jon Hallff566d52016-01-15 14:45:36 -08001858 main.log.error( handle )
pingping-lin8244a3b2015-09-16 13:36:56 -07001859 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001860 except AssertionError:
1861 main.log.exception( "" )
1862 return None
1863 except ( TypeError, ValueError ):
1864 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001865 return None
1866 except pexpect.EOF:
1867 main.log.error( self.name + ": EOF exception found" )
1868 main.log.error( self.name + ": " + self.handle.before )
1869 main.cleanup()
1870 main.exit()
1871 except Exception:
1872 main.log.exception( self.name + ": Uncaught exception!" )
1873 main.cleanup()
1874 main.exit()
1875
kelvin-onlab54400a92015-02-26 18:05:51 -08001876 def getIntentState(self, intentsId, intentsJson=None):
1877 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001878 Check intent state.
1879 Accepts a single intent ID (string type) or a list of intent IDs.
1880 Returns the state(string type) of the id if a single intent ID is
1881 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001882 Returns a dictionary with intent IDs as the key and its
1883 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001884 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001885 intentId: intent ID (string type)
1886 intentsJson: parsed json object from the onos:intents api
1887 Returns:
1888 state = An intent's state- INSTALL,WITHDRAWN etc.
1889 stateDict = Dictionary of intent's state. intent ID as the keys and
1890 state as the values.
1891 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001892 try:
1893 state = "State is Undefined"
1894 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001895 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001896 else:
Jon Hallc6793552016-01-19 14:18:37 -08001897 rawJson = intentsJson
1898 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001899 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001900 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001901 if intentsId == intent[ 'id' ]:
1902 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001903 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001904 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1905 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001906 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001907 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001908 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001909 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001910 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001911 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001912 if intentsId[ i ] == intents[ 'id' ]:
1913 stateDict[ 'state' ] = intents[ 'state' ]
1914 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001915 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001916 break
Jon Hallefbd9792015-03-05 16:11:36 -08001917 if len( intentsId ) != len( dictList ):
1918 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001919 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001920 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001921 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001922 return None
Jon Hallc6793552016-01-19 14:18:37 -08001923 except ( TypeError, ValueError ):
1924 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001925 return None
1926 except pexpect.EOF:
1927 main.log.error( self.name + ": EOF exception found" )
1928 main.log.error( self.name + ": " + self.handle.before )
1929 main.cleanup()
1930 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001931 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001932 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001933 main.cleanup()
1934 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001935
kelvin-onlabf512e942015-06-08 19:42:59 -07001936 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001937 """
1938 Description:
1939 Check intents state
1940 Required:
1941 intentsId - List of intents ID to be checked
1942 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07001943 expectedState - Check the expected state(s) of each intents
1944 state in the list.
1945 *NOTE: You can pass in a list of expected state,
1946 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001947 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07001948 Returns main.TRUE only if all intent are the same as expected states
1949 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001950 """
1951 try:
1952 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07001953 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001954 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001955 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08001956 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001957 "getting intents state" )
1958 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001959
1960 if isinstance( expectedState, types.StringType ):
1961 for intents in intentsDict:
1962 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001963 main.log.debug( self.name + " : Intent ID - " +
1964 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001965 " actual state = " +
1966 intents.get( 'state' )
1967 + " does not equal expected state = "
1968 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07001969 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07001970
1971 elif isinstance( expectedState, types.ListType ):
1972 for intents in intentsDict:
1973 if not any( state == intents.get( 'state' ) for state in
1974 expectedState ):
1975 main.log.debug( self.name + " : Intent ID - " +
1976 intents.get( 'id' ) +
1977 " actual state = " +
1978 intents.get( 'state' ) +
1979 " does not equal expected states = "
1980 + str( expectedState ) )
1981 returnValue = main.FALSE
1982
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001983 if returnValue == main.TRUE:
1984 main.log.info( self.name + ": All " +
1985 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07001986 " intents are in " + str( expectedState ) +
1987 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001988 return returnValue
1989 except TypeError:
1990 main.log.exception( self.name + ": Object not as expected" )
1991 return None
1992 except pexpect.EOF:
1993 main.log.error( self.name + ": EOF exception found" )
1994 main.log.error( self.name + ": " + self.handle.before )
1995 main.cleanup()
1996 main.exit()
1997 except Exception:
1998 main.log.exception( self.name + ": Uncaught exception!" )
1999 main.cleanup()
2000 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002001
GlennRCed771242016-01-13 17:02:47 -08002002 def checkIntentSummary( self, timeout=60 ):
2003 """
2004 Description:
2005 Check the number of installed intents.
2006 Optional:
2007 timeout - the timeout for pexcept
2008 Return:
2009 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2010 , otherwise, returns main.FALSE.
2011 """
2012
2013 try:
2014 cmd = "intents -s -j"
2015
2016 # Check response if something wrong
2017 response = self.sendline( cmd, timeout=timeout )
2018 if response == None:
2019 return main.False
2020 response = json.loads( response )
2021
2022 # get total and installed number, see if they are match
2023 allState = response.get( 'all' )
2024 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002025 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002026 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002027 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002028 return main.FALSE
2029
Jon Hallc6793552016-01-19 14:18:37 -08002030 except ( TypeError, ValueError ):
2031 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002032 return None
2033 except pexpect.EOF:
2034 main.log.error( self.name + ": EOF exception found" )
2035 main.log.error( self.name + ": " + self.handle.before )
2036 main.cleanup()
2037 main.exit()
2038 except Exception:
2039 main.log.exception( self.name + ": Uncaught exception!" )
2040 main.cleanup()
2041 main.exit()
2042
2043 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002044 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002045 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002046 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002047 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002048 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002049 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002051 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002052 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002053 cmdStr += " -j "
2054 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002055 handle = self.sendline( cmdStr, timeout=timeout )
2056 assert "Command not found:" not in handle, handle
2057 if re.search( "Error:", handle ):
2058 main.log.error( self.name + ": flows() response: " +
2059 str( handle ) )
2060 return handle
2061 except AssertionError:
2062 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002063 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002064 except TypeError:
2065 main.log.exception( self.name + ": Object not as expected" )
2066 return None
Jon Hallc6793552016-01-19 14:18:37 -08002067 except pexpect.TIMEOUT:
2068 main.log.error( self.name + ": ONOS timeout" )
2069 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002071 main.log.error( self.name + ": EOF exception found" )
2072 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002073 main.cleanup()
2074 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002076 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002077 main.cleanup()
2078 main.exit()
2079
GlennRCed771242016-01-13 17:02:47 -08002080
Jon Hallc6793552016-01-19 14:18:37 -08002081 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002082 """
2083 Description:
GlennRCed771242016-01-13 17:02:47 -08002084 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002085 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2086 if the count of those states is 0, which means all current flows
2087 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002088 Optional:
GlennRCed771242016-01-13 17:02:47 -08002089 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002090 Return:
2091 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002092 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002093 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002094 """
2095 try:
GlennRCed771242016-01-13 17:02:47 -08002096 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2097 checkedStates = []
2098 statesCount = [0, 0, 0, 0]
2099 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002100 rawFlows = self.flows( state=s, timeout = timeout )
2101 checkedStates.append( json.loads( rawFlows ) )
2102 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002103 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002104 try:
2105 statesCount[i] += int( c.get( "flowCount" ) )
2106 except TypeError:
2107 main.log.exception( "Json object not as expected" )
2108 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002109
GlennRCed771242016-01-13 17:02:47 -08002110 # We want to count PENDING_ADD if isPENDING is true
2111 if isPENDING:
2112 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2113 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002114 else:
GlennRCed771242016-01-13 17:02:47 -08002115 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2116 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002117 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002118 except ( TypeError, ValueError ):
2119 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002120 return None
2121 except pexpect.EOF:
2122 main.log.error( self.name + ": EOF exception found" )
2123 main.log.error( self.name + ": " + self.handle.before )
2124 main.cleanup()
2125 main.exit()
2126 except Exception:
2127 main.log.exception( self.name + ": Uncaught exception!" )
2128 main.cleanup()
2129 main.exit()
2130
GlennRCed771242016-01-13 17:02:47 -08002131 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2132 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002133 """
andrewonlab87852b02014-11-19 18:44:19 -05002134 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002135 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002136 a specific point-to-point intent definition
2137 Required:
GlennRCed771242016-01-13 17:02:47 -08002138 * ingress: specify source dpid
2139 * egress: specify destination dpid
2140 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002141 Optional:
GlennRCed771242016-01-13 17:02:47 -08002142 * offset: the keyOffset is where the next batch of intents
2143 will be installed
2144 Returns: If failed to push test intents, it will returen None,
2145 if successful, return true.
2146 Timeout expection will return None,
2147 TypeError will return false
2148 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002149 """
andrewonlab87852b02014-11-19 18:44:19 -05002150 try:
GlennRCed771242016-01-13 17:02:47 -08002151 if background:
2152 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002153 else:
GlennRCed771242016-01-13 17:02:47 -08002154 back = ""
2155 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002156 ingress,
2157 egress,
2158 batchSize,
2159 offset,
2160 back )
GlennRCed771242016-01-13 17:02:47 -08002161 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002162 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002163 main.log.info( response )
2164 if response == None:
2165 return None
2166
2167 # TODO: We should handle if there is failure in installation
2168 return main.TRUE
2169
Jon Hallc6793552016-01-19 14:18:37 -08002170 except AssertionError:
2171 main.log.exception( "" )
2172 return None
GlennRCed771242016-01-13 17:02:47 -08002173 except pexpect.TIMEOUT:
2174 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002175 return None
andrewonlab87852b02014-11-19 18:44:19 -05002176 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002177 main.log.error( self.name + ": EOF exception found" )
2178 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002179 main.cleanup()
2180 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002181 except TypeError:
2182 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002183 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002184 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002185 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002186 main.cleanup()
2187 main.exit()
2188
YPZhangb5d3f832016-01-23 22:54:26 -08002189 def getTotalFlowsNum( self ):
2190 """
2191 Description:
2192 Get the total number of flows, include every states.
2193 Return:
2194 The number of flows
2195 """
2196 try:
2197 cmd = "summary -j"
2198 response = self.sendline( cmd )
2199 if response == None:
2200 return -1
2201 response = json.loads( response )
2202 return int( response.get("flows") )
2203 except TypeError:
2204 main.log.exception( self.name + ": Object not as expected" )
2205 return None
2206 except pexpect.EOF:
2207 main.log.error( self.name + ": EOF exception found" )
2208 main.log.error( self.name + ": " + self.handle.before )
2209 main.cleanup()
2210 main.exit()
2211 except Exception:
2212 main.log.exception( self.name + ": Uncaught exception!" )
2213 main.cleanup()
2214 main.exit()
2215
2216 def getTotalIntentsNum( self ):
2217 """
2218 Description:
2219 Get the total number of intents, include every states.
2220 Return:
2221 The number of intents
2222 """
2223 try:
2224 cmd = "summary -j"
2225 response = self.sendline( cmd )
2226 if response == None:
2227 return -1
2228 response = json.loads( response )
2229 return int( response.get("intents") )
2230 except TypeError:
2231 main.log.exception( self.name + ": Object not as expected" )
2232 return None
2233 except pexpect.EOF:
2234 main.log.error( self.name + ": EOF exception found" )
2235 main.log.error( self.name + ": " + self.handle.before )
2236 main.cleanup()
2237 main.exit()
2238 except Exception:
2239 main.log.exception( self.name + ": Uncaught exception!" )
2240 main.cleanup()
2241 main.exit()
2242
kelvin-onlabd3b64892015-01-20 13:26:24 -08002243 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002244 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002245 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002246 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002247 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002248 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002249 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002250 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002252 cmdStr += " -j"
2253 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002254 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002255 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002256 except AssertionError:
2257 main.log.exception( "" )
2258 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002259 except TypeError:
2260 main.log.exception( self.name + ": Object not as expected" )
2261 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002262 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002263 main.log.error( self.name + ": EOF exception found" )
2264 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002265 main.cleanup()
2266 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002267 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002268 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002269 main.cleanup()
2270 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002271
kelvin-onlabd3b64892015-01-20 13:26:24 -08002272 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002273 """
2274 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002275 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002276 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002277 """
andrewonlab867212a2014-10-22 20:13:38 -04002278 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002279 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002280 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002281 cmdStr += " -j"
2282 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002283 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002284 if handle:
2285 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002286 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002287 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002288 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002289 else:
2290 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002291 except AssertionError:
2292 main.log.exception( "" )
2293 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002294 except TypeError:
2295 main.log.exception( self.name + ": Object not as expected" )
2296 return None
andrewonlab867212a2014-10-22 20:13:38 -04002297 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002298 main.log.error( self.name + ": EOF exception found" )
2299 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002300 main.cleanup()
2301 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002303 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002304 main.cleanup()
2305 main.exit()
2306
kelvin8ec71442015-01-15 16:57:00 -08002307 # Wrapper functions ****************
2308 # Wrapper functions use existing driver
2309 # functions and extends their use case.
2310 # For example, we may use the output of
2311 # a normal driver function, and parse it
2312 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002313
kelvin-onlabd3b64892015-01-20 13:26:24 -08002314 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002315 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002316 Description:
2317 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002318 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002319 try:
kelvin8ec71442015-01-15 16:57:00 -08002320 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002321 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002322 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002323
kelvin8ec71442015-01-15 16:57:00 -08002324 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002325 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2326 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002327 match = re.search('id=0x([\da-f]+),', intents)
2328 if match:
2329 tmpId = match.group()[3:-1]
2330 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002331 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002332
Jon Halld4d4b372015-01-28 16:02:41 -08002333 except TypeError:
2334 main.log.exception( self.name + ": Object not as expected" )
2335 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002336 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002337 main.log.error( self.name + ": EOF exception found" )
2338 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002339 main.cleanup()
2340 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002341 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002342 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002343 main.cleanup()
2344 main.exit()
2345
Jon Hall30b82fa2015-03-04 17:15:43 -08002346 def FlowAddedCount( self, deviceId ):
2347 """
2348 Determine the number of flow rules for the given device id that are
2349 in the added state
2350 """
2351 try:
2352 cmdStr = "flows any " + str( deviceId ) + " | " +\
2353 "grep 'state=ADDED' | wc -l"
2354 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002355 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002356 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002357 except AssertionError:
2358 main.log.exception( "" )
2359 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002360 except pexpect.EOF:
2361 main.log.error( self.name + ": EOF exception found" )
2362 main.log.error( self.name + ": " + self.handle.before )
2363 main.cleanup()
2364 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002365 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002366 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002367 main.cleanup()
2368 main.exit()
2369
kelvin-onlabd3b64892015-01-20 13:26:24 -08002370 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002371 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002372 Use 'devices' function to obtain list of all devices
2373 and parse the result to obtain a list of all device
2374 id's. Returns this list. Returns empty list if no
2375 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002376 List is ordered sequentially
2377
andrewonlab3e15ead2014-10-15 14:21:34 -04002378 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002379 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002380 the ids. By obtaining the list of device ids on the fly,
2381 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002382 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002383 try:
kelvin8ec71442015-01-15 16:57:00 -08002384 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002385 devicesStr = self.devices( jsonFormat=False )
2386 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002387
kelvin-onlabd3b64892015-01-20 13:26:24 -08002388 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002389 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002390 return idList
kelvin8ec71442015-01-15 16:57:00 -08002391
2392 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002393 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002394 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002395 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002396 # Split list further into arguments before and after string
2397 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002398 # append to idList
2399 for arg in tempList:
2400 idList.append( arg.split( "id=" )[ 1 ] )
2401 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002402
Jon Halld4d4b372015-01-28 16:02:41 -08002403 except TypeError:
2404 main.log.exception( self.name + ": Object not as expected" )
2405 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002406 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002407 main.log.error( self.name + ": EOF exception found" )
2408 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002409 main.cleanup()
2410 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002411 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002412 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002413 main.cleanup()
2414 main.exit()
2415
kelvin-onlabd3b64892015-01-20 13:26:24 -08002416 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002417 """
andrewonlab7c211572014-10-15 16:45:20 -04002418 Uses 'nodes' function to obtain list of all nodes
2419 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002420 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002421 Returns:
2422 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002423 """
andrewonlab7c211572014-10-15 16:45:20 -04002424 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002425 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002426 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002427 # Sample nodesStr output
2428 # id=local, address=127.0.0.1:9876, state=ACTIVE *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002429 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002430 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002431 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002432 nodesJson = json.loads( nodesStr )
2433 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002434 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002435 except ( TypeError, ValueError ):
2436 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002437 return None
andrewonlab7c211572014-10-15 16:45:20 -04002438 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002439 main.log.error( self.name + ": EOF exception found" )
2440 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002441 main.cleanup()
2442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002444 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002445 main.cleanup()
2446 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002447
kelvin-onlabd3b64892015-01-20 13:26:24 -08002448 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002449 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002450 Return the first device from the devices api whose 'id' contains 'dpid'
2451 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002452 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002453 try:
kelvin8ec71442015-01-15 16:57:00 -08002454 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002455 return None
2456 else:
kelvin8ec71442015-01-15 16:57:00 -08002457 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 rawDevices = self.devices()
2459 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002460 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002461 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002462 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2463 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002464 return device
2465 return None
Jon Hallc6793552016-01-19 14:18:37 -08002466 except ( TypeError, ValueError ):
2467 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002468 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002469 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002470 main.log.error( self.name + ": EOF exception found" )
2471 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002472 main.cleanup()
2473 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002474 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002475 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002476 main.cleanup()
2477 main.exit()
2478
kelvin-onlabd3b64892015-01-20 13:26:24 -08002479 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002480 """
Jon Hallefbd9792015-03-05 16:11:36 -08002481 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002482 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002483 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002484
Jon Hall42db6dc2014-10-24 19:03:48 -04002485 Params: ip = ip used for the onos cli
2486 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002487 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 logLevel = level to log to. Currently accepts
2489 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002490
2491
kelvin-onlabd3b64892015-01-20 13:26:24 -08002492 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002493
Jon Hallefbd9792015-03-05 16:11:36 -08002494 Returns: main.TRUE if the number of switches and links are correct,
2495 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002496 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002497 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002498 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002499 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002500 if topology == {}:
2501 return main.ERROR
2502 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002503 # Is the number of switches is what we expected
2504 devices = topology.get( 'devices', False )
2505 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002506 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002507 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002509 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 linkCheck = ( int( links ) == int( numolink ) )
2511 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002512 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002513 output += "The number of links and switches match " +\
2514 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002515 result = main.TRUE
2516 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002517 output += "The number of links and switches does not match " +\
2518 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002519 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002520 output = output + "\n ONOS sees %i devices (%i expected) \
2521 and %i links (%i expected)" % (
2522 int( devices ), int( numoswitch ), int( links ),
2523 int( numolink ) )
2524 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002525 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002526 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002527 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002528 else:
Jon Hall390696c2015-05-05 17:13:41 -07002529 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002530 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002531 except TypeError:
2532 main.log.exception( self.name + ": Object not as expected" )
2533 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002535 main.log.error( self.name + ": EOF exception found" )
2536 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002537 main.cleanup()
2538 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002540 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002541 main.cleanup()
2542 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002543
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002545 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002546 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002547 deviceId must be the id of a device as seen in the onos devices command
2548 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002549 role must be either master, standby, or none
2550
Jon Halle3f39ff2015-01-13 11:50:53 -08002551 Returns:
2552 main.TRUE or main.FALSE based on argument verification and
2553 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002554 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002555 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002556 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002557 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002558 cmdStr = "device-role " +\
2559 str( deviceId ) + " " +\
2560 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002561 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002562 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002563 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002564 if re.search( "Error", handle ):
2565 # end color output to escape any colours
2566 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002567 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002568 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002569 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002570 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002571 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002572 main.log.error( "Invalid 'role' given to device_role(). " +
2573 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002574 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002575 except AssertionError:
2576 main.log.exception( "" )
2577 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002578 except TypeError:
2579 main.log.exception( self.name + ": Object not as expected" )
2580 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002582 main.log.error( self.name + ": EOF exception found" )
2583 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002584 main.cleanup()
2585 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002586 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002587 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002588 main.cleanup()
2589 main.exit()
2590
kelvin-onlabd3b64892015-01-20 13:26:24 -08002591 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002592 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002593 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002594 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002595 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002596 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002597 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002598 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002599 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002600 cmdStr += " -j"
2601 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002602 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002603 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002604 except AssertionError:
2605 main.log.exception( "" )
2606 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002607 except TypeError:
2608 main.log.exception( self.name + ": Object not as expected" )
2609 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002611 main.log.error( self.name + ": EOF exception found" )
2612 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002613 main.cleanup()
2614 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002615 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002616 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002617 main.cleanup()
2618 main.exit()
2619
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002621 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002622 CLI command to get the current leader for the Election test application
2623 NOTE: Requires installation of the onos-app-election feature
2624 Returns: Node IP of the leader if one exists
2625 None if none exists
2626 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002627 """
Jon Hall94fd0472014-12-08 11:52:42 -08002628 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002629 cmdStr = "election-test-leader"
2630 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002631 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002632 # Leader
2633 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002634 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002635 nodeSearch = re.search( leaderPattern, response )
2636 if nodeSearch:
2637 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002638 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002639 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002640 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002641 # no leader
2642 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002643 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 nullSearch = re.search( nullPattern, response )
2645 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002646 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002647 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002648 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002649 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002650 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002651 if re.search( errorPattern, response ):
2652 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002653 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002654 return main.FALSE
2655 else:
Jon Hall390696c2015-05-05 17:13:41 -07002656 main.log.error( "Error in electionTestLeader on " + self.name +
2657 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002658 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002659 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002660 except AssertionError:
2661 main.log.exception( "" )
2662 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002663 except TypeError:
2664 main.log.exception( self.name + ": Object not as expected" )
2665 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002666 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002667 main.log.error( self.name + ": EOF exception found" )
2668 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002669 main.cleanup()
2670 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002671 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002672 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002673 main.cleanup()
2674 main.exit()
2675
kelvin-onlabd3b64892015-01-20 13:26:24 -08002676 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002677 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002678 CLI command to run for leadership of the Election test application.
2679 NOTE: Requires installation of the onos-app-election feature
2680 Returns: Main.TRUE on success
2681 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002682 """
Jon Hall94fd0472014-12-08 11:52:42 -08002683 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 cmdStr = "election-test-run"
2685 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002686 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002687 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002688 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002689 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002690 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002691 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002692 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002693 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002694 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002695 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002696 errorPattern = "Command\snot\sfound"
2697 if re.search( errorPattern, response ):
2698 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002699 return main.FALSE
2700 else:
Jon Hall390696c2015-05-05 17:13:41 -07002701 main.log.error( "Error in electionTestRun on " + self.name +
2702 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002703 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002704 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002705 except AssertionError:
2706 main.log.exception( "" )
2707 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002708 except TypeError:
2709 main.log.exception( self.name + ": Object not as expected" )
2710 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002711 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002712 main.log.error( self.name + ": EOF exception found" )
2713 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002714 main.cleanup()
2715 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002716 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002717 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002718 main.cleanup()
2719 main.exit()
2720
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002722 """
Jon Hall94fd0472014-12-08 11:52:42 -08002723 * CLI command to withdraw the local node from leadership election for
2724 * the Election test application.
2725 #NOTE: Requires installation of the onos-app-election feature
2726 Returns: Main.TRUE on success
2727 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002728 """
Jon Hall94fd0472014-12-08 11:52:42 -08002729 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002730 cmdStr = "election-test-withdraw"
2731 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002732 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002733 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002734 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002735 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002736 if re.search( successPattern, response ):
2737 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002738 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002739 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002740 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002741 errorPattern = "Command\snot\sfound"
2742 if re.search( errorPattern, response ):
2743 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002744 return main.FALSE
2745 else:
Jon Hall390696c2015-05-05 17:13:41 -07002746 main.log.error( "Error in electionTestWithdraw on " +
2747 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002748 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002749 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002750 except AssertionError:
2751 main.log.exception( "" )
2752 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002753 except TypeError:
2754 main.log.exception( self.name + ": Object not as expected" )
2755 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002757 main.log.error( self.name + ": EOF exception found" )
2758 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002759 main.cleanup()
2760 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002761 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002762 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002763 main.cleanup()
2764 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002765
kelvin8ec71442015-01-15 16:57:00 -08002766 def getDevicePortsEnabledCount( self, dpid ):
2767 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002768 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002769 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002770 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002771 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002772 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2773 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002774 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002775 if re.search( "No such device", output ):
2776 main.log.error( "Error in getting ports" )
2777 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002778 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002779 return output
Jon Hallc6793552016-01-19 14:18:37 -08002780 except AssertionError:
2781 main.log.exception( "" )
2782 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002783 except TypeError:
2784 main.log.exception( self.name + ": Object not as expected" )
2785 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002786 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002787 main.log.error( self.name + ": EOF exception found" )
2788 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002789 main.cleanup()
2790 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002791 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002792 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002793 main.cleanup()
2794 main.exit()
2795
kelvin8ec71442015-01-15 16:57:00 -08002796 def getDeviceLinksActiveCount( self, dpid ):
2797 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002798 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002799 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002800 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002801 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002802 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2803 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002804 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002805 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002806 main.log.error( "Error in getting ports " )
2807 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002808 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002809 return output
Jon Hallc6793552016-01-19 14:18:37 -08002810 except AssertionError:
2811 main.log.exception( "" )
2812 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002813 except TypeError:
2814 main.log.exception( self.name + ": Object not as expected" )
2815 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002816 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002817 main.log.error( self.name + ": EOF exception found" )
2818 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002819 main.cleanup()
2820 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002821 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002822 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002823 main.cleanup()
2824 main.exit()
2825
kelvin8ec71442015-01-15 16:57:00 -08002826 def getAllIntentIds( self ):
2827 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002828 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002829 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002830 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 cmdStr = "onos:intents | grep id="
2832 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002833 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002834 if re.search( "Error", output ):
2835 main.log.error( "Error in getting ports" )
2836 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002837 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002838 return output
Jon Hallc6793552016-01-19 14:18:37 -08002839 except AssertionError:
2840 main.log.exception( "" )
2841 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002842 except TypeError:
2843 main.log.exception( self.name + ": Object not as expected" )
2844 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002845 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002846 main.log.error( self.name + ": EOF exception found" )
2847 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002848 main.cleanup()
2849 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002850 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002851 main.log.exception( self.name + ": Uncaught exception!" )
2852 main.cleanup()
2853 main.exit()
2854
Jon Hall73509952015-02-24 16:42:56 -08002855 def intentSummary( self ):
2856 """
Jon Hallefbd9792015-03-05 16:11:36 -08002857 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002858 """
2859 try:
2860 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002861 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002862 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002863 states.append( intent.get( 'state', None ) )
2864 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002865 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002866 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002867 except ( TypeError, ValueError ):
2868 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002869 return None
2870 except pexpect.EOF:
2871 main.log.error( self.name + ": EOF exception found" )
2872 main.log.error( self.name + ": " + self.handle.before )
2873 main.cleanup()
2874 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002875 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002876 main.log.exception( self.name + ": Uncaught exception!" )
2877 main.cleanup()
2878 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002879
Jon Hall61282e32015-03-19 11:34:11 -07002880 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002881 """
2882 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002883 Optional argument:
2884 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002885 """
Jon Hall63604932015-02-26 17:09:50 -08002886 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002887 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002888 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002889 cmdStr += " -j"
2890 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002891 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002892 return output
Jon Hallc6793552016-01-19 14:18:37 -08002893 except AssertionError:
2894 main.log.exception( "" )
2895 return None
Jon Hall63604932015-02-26 17:09:50 -08002896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002899 except pexpect.EOF:
2900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
2902 main.cleanup()
2903 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002904 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002905 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002906 main.cleanup()
2907 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002908
acsmarsa4a4d1e2015-07-10 16:01:24 -07002909 def leaderCandidates( self, jsonFormat=True ):
2910 """
2911 Returns the output of the leaders -c command.
2912 Optional argument:
2913 * jsonFormat - boolean indicating if you want output in json
2914 """
2915 try:
2916 cmdStr = "onos:leaders -c"
2917 if jsonFormat:
2918 cmdStr += " -j"
2919 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002920 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07002921 return output
Jon Hallc6793552016-01-19 14:18:37 -08002922 except AssertionError:
2923 main.log.exception( "" )
2924 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07002925 except TypeError:
2926 main.log.exception( self.name + ": Object not as expected" )
2927 return None
2928 except pexpect.EOF:
2929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
2931 main.cleanup()
2932 main.exit()
2933 except Exception:
2934 main.log.exception( self.name + ": Uncaught exception!" )
2935 main.cleanup()
2936 main.exit()
2937
Jon Hallc6793552016-01-19 14:18:37 -08002938 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07002939 """
2940 Returns a list in format [leader,candidate1,candidate2,...] for a given
2941 topic parameter and an empty list if the topic doesn't exist
2942 If no leader is elected leader in the returned list will be "none"
2943 Returns None if there is a type error processing the json object
2944 """
2945 try:
2946 cmdStr = "onos:leaders -c -j"
Jon Hallc6793552016-01-19 14:18:37 -08002947 rawOutput = self.sendline( cmdStr )
2948 assert "Command not found:" not in rawOutput, rawOutput
2949 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002950 results = []
2951 for dict in output:
2952 if dict["topic"] == topic:
2953 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08002954 candidates = re.split( ", ", dict["candidates"][1:-1] )
2955 results.append( leader )
2956 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002957 return results
Jon Hallc6793552016-01-19 14:18:37 -08002958 except AssertionError:
2959 main.log.exception( "" )
2960 return None
2961 except ( TypeError, ValueError ):
2962 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07002963 return None
2964 except pexpect.EOF:
2965 main.log.error( self.name + ": EOF exception found" )
2966 main.log.error( self.name + ": " + self.handle.before )
2967 main.cleanup()
2968 main.exit()
2969 except Exception:
2970 main.log.exception( self.name + ": Uncaught exception!" )
2971 main.cleanup()
2972 main.exit()
2973
Jon Hall61282e32015-03-19 11:34:11 -07002974 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002975 """
2976 Returns the output of the intent Pending map.
2977 """
Jon Hall63604932015-02-26 17:09:50 -08002978 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002979 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07002980 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002981 cmdStr += " -j"
2982 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002983 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002984 return output
Jon Hallc6793552016-01-19 14:18:37 -08002985 except AssertionError:
2986 main.log.exception( "" )
2987 return None
Jon Hall63604932015-02-26 17:09:50 -08002988 except TypeError:
2989 main.log.exception( self.name + ": Object not as expected" )
2990 return None
2991 except pexpect.EOF:
2992 main.log.error( self.name + ": EOF exception found" )
2993 main.log.error( self.name + ": " + self.handle.before )
2994 main.cleanup()
2995 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002996 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002997 main.log.exception( self.name + ": Uncaught exception!" )
2998 main.cleanup()
2999 main.exit()
3000
Jon Hall61282e32015-03-19 11:34:11 -07003001 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003002 """
3003 Returns the output of the raft partitions command for ONOS.
3004 """
Jon Hall61282e32015-03-19 11:34:11 -07003005 # Sample JSON
3006 # {
3007 # "leader": "tcp://10.128.30.11:7238",
3008 # "members": [
3009 # "tcp://10.128.30.11:7238",
3010 # "tcp://10.128.30.17:7238",
3011 # "tcp://10.128.30.13:7238",
3012 # ],
3013 # "name": "p1",
3014 # "term": 3
3015 # },
Jon Hall63604932015-02-26 17:09:50 -08003016 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003017 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003018 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003019 cmdStr += " -j"
3020 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003021 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003022 return output
Jon Hallc6793552016-01-19 14:18:37 -08003023 except AssertionError:
3024 main.log.exception( "" )
3025 return None
Jon Hall63604932015-02-26 17:09:50 -08003026 except TypeError:
3027 main.log.exception( self.name + ": Object not as expected" )
3028 return None
3029 except pexpect.EOF:
3030 main.log.error( self.name + ": EOF exception found" )
3031 main.log.error( self.name + ": " + self.handle.before )
3032 main.cleanup()
3033 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003034 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003035 main.log.exception( self.name + ": Uncaught exception!" )
3036 main.cleanup()
3037 main.exit()
3038
Jon Hallbe379602015-03-24 13:39:32 -07003039 def apps( self, jsonFormat=True ):
3040 """
3041 Returns the output of the apps command for ONOS. This command lists
3042 information about installed ONOS applications
3043 """
3044 # Sample JSON object
3045 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3046 # "description":"ONOS OpenFlow protocol southbound providers",
3047 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3048 # "features":"[onos-openflow]","state":"ACTIVE"}]
3049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003050 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003051 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003052 cmdStr += " -j"
3053 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003054 assert "Command not found:" not in output, output
3055 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003056 return output
Jon Hallbe379602015-03-24 13:39:32 -07003057 # FIXME: look at specific exceptions/Errors
3058 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003059 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003060 return None
3061 except TypeError:
3062 main.log.exception( self.name + ": Object not as expected" )
3063 return None
3064 except pexpect.EOF:
3065 main.log.error( self.name + ": EOF exception found" )
3066 main.log.error( self.name + ": " + self.handle.before )
3067 main.cleanup()
3068 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003069 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003070 main.log.exception( self.name + ": Uncaught exception!" )
3071 main.cleanup()
3072 main.exit()
3073
Jon Hall146f1522015-03-24 15:33:24 -07003074 def appStatus( self, appName ):
3075 """
3076 Uses the onos:apps cli command to return the status of an application.
3077 Returns:
3078 "ACTIVE" - If app is installed and activated
3079 "INSTALLED" - If app is installed and deactivated
3080 "UNINSTALLED" - If app is not installed
3081 None - on error
3082 """
Jon Hall146f1522015-03-24 15:33:24 -07003083 try:
3084 if not isinstance( appName, types.StringType ):
3085 main.log.error( self.name + ".appStatus(): appName must be" +
3086 " a string" )
3087 return None
3088 output = self.apps( jsonFormat=True )
3089 appsJson = json.loads( output )
3090 state = None
3091 for app in appsJson:
3092 if appName == app.get('name'):
3093 state = app.get('state')
3094 break
3095 if state == "ACTIVE" or state == "INSTALLED":
3096 return state
3097 elif state is None:
3098 return "UNINSTALLED"
3099 elif state:
3100 main.log.error( "Unexpected state from 'onos:apps': " +
3101 str( state ) )
3102 return state
Jon Hallc6793552016-01-19 14:18:37 -08003103 except ( TypeError, ValueError ):
3104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
3105 main.stop()
Jon Hall146f1522015-03-24 15:33:24 -07003106 return None
3107 except pexpect.EOF:
3108 main.log.error( self.name + ": EOF exception found" )
3109 main.log.error( self.name + ": " + self.handle.before )
3110 main.cleanup()
3111 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003112 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003113 main.log.exception( self.name + ": Uncaught exception!" )
3114 main.cleanup()
3115 main.exit()
3116
Jon Hallbe379602015-03-24 13:39:32 -07003117 def app( self, appName, option ):
3118 """
3119 Interacts with the app command for ONOS. This command manages
3120 application inventory.
3121 """
Jon Hallbe379602015-03-24 13:39:32 -07003122 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003123 # Validate argument types
3124 valid = True
3125 if not isinstance( appName, types.StringType ):
3126 main.log.error( self.name + ".app(): appName must be a " +
3127 "string" )
3128 valid = False
3129 if not isinstance( option, types.StringType ):
3130 main.log.error( self.name + ".app(): option must be a string" )
3131 valid = False
3132 if not valid:
3133 return main.FALSE
3134 # Validate Option
3135 option = option.lower()
3136 # NOTE: Install may become a valid option
3137 if option == "activate":
3138 pass
3139 elif option == "deactivate":
3140 pass
3141 elif option == "uninstall":
3142 pass
3143 else:
3144 # Invalid option
3145 main.log.error( "The ONOS app command argument only takes " +
3146 "the values: (activate|deactivate|uninstall)" +
3147 "; was given '" + option + "'")
3148 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003149 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003150 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003151 if "Error executing command" in output:
3152 main.log.error( "Error in processing onos:app command: " +
3153 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003154 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003155 elif "No such application" in output:
3156 main.log.error( "The application '" + appName +
3157 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003158 return main.FALSE
3159 elif "Command not found:" in output:
3160 main.log.error( "Error in processing onos:app command: " +
3161 str( output ) )
3162 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003163 elif "Unsupported command:" in output:
3164 main.log.error( "Incorrect command given to 'app': " +
3165 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003166 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003167 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003168 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003169 return main.TRUE
3170 except TypeError:
3171 main.log.exception( self.name + ": Object not as expected" )
3172 return main.ERROR
3173 except pexpect.EOF:
3174 main.log.error( self.name + ": EOF exception found" )
3175 main.log.error( self.name + ": " + self.handle.before )
3176 main.cleanup()
3177 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003178 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003179 main.log.exception( self.name + ": Uncaught exception!" )
3180 main.cleanup()
3181 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003182
Jon Hallbd16b922015-03-26 17:53:15 -07003183 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003184 """
3185 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003186 appName is the hierarchical app name, not the feature name
3187 If check is True, method will check the status of the app after the
3188 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003189 Returns main.TRUE if the command was successfully sent
3190 main.FALSE if the cli responded with an error or given
3191 incorrect input
3192 """
3193 try:
3194 if not isinstance( appName, types.StringType ):
3195 main.log.error( self.name + ".activateApp(): appName must be" +
3196 " a string" )
3197 return main.FALSE
3198 status = self.appStatus( appName )
3199 if status == "INSTALLED":
3200 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003201 if check and response == main.TRUE:
3202 for i in range(10): # try 10 times then give up
3203 # TODO: Check with Thomas about this delay
3204 status = self.appStatus( appName )
3205 if status == "ACTIVE":
3206 return main.TRUE
3207 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003208 main.log.debug( "The state of application " +
3209 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003210 time.sleep( 1 )
3211 return main.FALSE
3212 else: # not 'check' or command didn't succeed
3213 return response
Jon Hall146f1522015-03-24 15:33:24 -07003214 elif status == "ACTIVE":
3215 return main.TRUE
3216 elif status == "UNINSTALLED":
3217 main.log.error( self.name + ": Tried to activate the " +
3218 "application '" + appName + "' which is not " +
3219 "installed." )
3220 else:
3221 main.log.error( "Unexpected return value from appStatus: " +
3222 str( status ) )
3223 return main.ERROR
3224 except TypeError:
3225 main.log.exception( self.name + ": Object not as expected" )
3226 return main.ERROR
3227 except pexpect.EOF:
3228 main.log.error( self.name + ": EOF exception found" )
3229 main.log.error( self.name + ": " + self.handle.before )
3230 main.cleanup()
3231 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003232 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003233 main.log.exception( self.name + ": Uncaught exception!" )
3234 main.cleanup()
3235 main.exit()
3236
Jon Hallbd16b922015-03-26 17:53:15 -07003237 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003238 """
3239 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003240 appName is the hierarchical app name, not the feature name
3241 If check is True, method will check the status of the app after the
3242 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003243 Returns main.TRUE if the command was successfully sent
3244 main.FALSE if the cli responded with an error or given
3245 incorrect input
3246 """
3247 try:
3248 if not isinstance( appName, types.StringType ):
3249 main.log.error( self.name + ".deactivateApp(): appName must " +
3250 "be a string" )
3251 return main.FALSE
3252 status = self.appStatus( appName )
3253 if status == "INSTALLED":
3254 return main.TRUE
3255 elif status == "ACTIVE":
3256 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003257 if check and response == main.TRUE:
3258 for i in range(10): # try 10 times then give up
3259 status = self.appStatus( appName )
3260 if status == "INSTALLED":
3261 return main.TRUE
3262 else:
3263 time.sleep( 1 )
3264 return main.FALSE
3265 else: # not check or command didn't succeed
3266 return response
Jon Hall146f1522015-03-24 15:33:24 -07003267 elif status == "UNINSTALLED":
3268 main.log.warn( self.name + ": Tried to deactivate the " +
3269 "application '" + appName + "' which is not " +
3270 "installed." )
3271 return main.TRUE
3272 else:
3273 main.log.error( "Unexpected return value from appStatus: " +
3274 str( status ) )
3275 return main.ERROR
3276 except TypeError:
3277 main.log.exception( self.name + ": Object not as expected" )
3278 return main.ERROR
3279 except pexpect.EOF:
3280 main.log.error( self.name + ": EOF exception found" )
3281 main.log.error( self.name + ": " + self.handle.before )
3282 main.cleanup()
3283 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003284 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003285 main.log.exception( self.name + ": Uncaught exception!" )
3286 main.cleanup()
3287 main.exit()
3288
Jon Hallbd16b922015-03-26 17:53:15 -07003289 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003290 """
3291 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003292 appName is the hierarchical app name, not the feature name
3293 If check is True, method will check the status of the app after the
3294 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003295 Returns main.TRUE if the command was successfully sent
3296 main.FALSE if the cli responded with an error or given
3297 incorrect input
3298 """
3299 # TODO: check with Thomas about the state machine for apps
3300 try:
3301 if not isinstance( appName, types.StringType ):
3302 main.log.error( self.name + ".uninstallApp(): appName must " +
3303 "be a string" )
3304 return main.FALSE
3305 status = self.appStatus( appName )
3306 if status == "INSTALLED":
3307 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003308 if check and response == main.TRUE:
3309 for i in range(10): # try 10 times then give up
3310 status = self.appStatus( appName )
3311 if status == "UNINSTALLED":
3312 return main.TRUE
3313 else:
3314 time.sleep( 1 )
3315 return main.FALSE
3316 else: # not check or command didn't succeed
3317 return response
Jon Hall146f1522015-03-24 15:33:24 -07003318 elif status == "ACTIVE":
3319 main.log.warn( self.name + ": Tried to uninstall the " +
3320 "application '" + appName + "' which is " +
3321 "currently active." )
3322 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003323 if check and response == main.TRUE:
3324 for i in range(10): # try 10 times then give up
3325 status = self.appStatus( appName )
3326 if status == "UNINSTALLED":
3327 return main.TRUE
3328 else:
3329 time.sleep( 1 )
3330 return main.FALSE
3331 else: # not check or command didn't succeed
3332 return response
Jon Hall146f1522015-03-24 15:33:24 -07003333 elif status == "UNINSTALLED":
3334 return main.TRUE
3335 else:
3336 main.log.error( "Unexpected return value from appStatus: " +
3337 str( status ) )
3338 return main.ERROR
3339 except TypeError:
3340 main.log.exception( self.name + ": Object not as expected" )
3341 return main.ERROR
3342 except pexpect.EOF:
3343 main.log.error( self.name + ": EOF exception found" )
3344 main.log.error( self.name + ": " + self.handle.before )
3345 main.cleanup()
3346 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003347 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003348 main.log.exception( self.name + ": Uncaught exception!" )
3349 main.cleanup()
3350 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003351
3352 def appIDs( self, jsonFormat=True ):
3353 """
3354 Show the mappings between app id and app names given by the 'app-ids'
3355 cli command
3356 """
3357 try:
3358 cmdStr = "app-ids"
3359 if jsonFormat:
3360 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003361 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003362 assert "Command not found:" not in output, output
3363 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003364 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003365 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003366 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003367 return None
3368 except TypeError:
3369 main.log.exception( self.name + ": Object not as expected" )
3370 return None
3371 except pexpect.EOF:
3372 main.log.error( self.name + ": EOF exception found" )
3373 main.log.error( self.name + ": " + self.handle.before )
3374 main.cleanup()
3375 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003376 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003377 main.log.exception( self.name + ": Uncaught exception!" )
3378 main.cleanup()
3379 main.exit()
3380
3381 def appToIDCheck( self ):
3382 """
3383 This method will check that each application's ID listed in 'apps' is
3384 the same as the ID listed in 'app-ids'. The check will also check that
3385 there are no duplicate IDs issued. Note that an app ID should be
3386 a globaly unique numerical identifier for app/app-like features. Once
3387 an ID is registered, the ID is never freed up so that if an app is
3388 reinstalled it will have the same ID.
3389
3390 Returns: main.TRUE if the check passes and
3391 main.FALSE if the check fails or
3392 main.ERROR if there is some error in processing the test
3393 """
3394 try:
Jon Hall390696c2015-05-05 17:13:41 -07003395 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003396 rawJson = self.appIDs( jsonFormat=True )
3397 if rawJson:
3398 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003399 else:
Jon Hallc6793552016-01-19 14:18:37 -08003400 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003401 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003402 rawJson = self.apps( jsonFormat=True )
3403 if rawJson:
3404 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003405 else:
Jon Hallc6793552016-01-19 14:18:37 -08003406 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003407 bail = True
3408 if bail:
3409 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003410 result = main.TRUE
3411 for app in apps:
3412 appID = app.get( 'id' )
3413 if appID is None:
3414 main.log.error( "Error parsing app: " + str( app ) )
3415 result = main.FALSE
3416 appName = app.get( 'name' )
3417 if appName is None:
3418 main.log.error( "Error parsing app: " + str( app ) )
3419 result = main.FALSE
3420 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003421 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003422 # main.log.debug( "Comparing " + str( app ) + " to " +
3423 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003424 if not current: # if ids doesn't have this id
3425 result = main.FALSE
3426 main.log.error( "'app-ids' does not have the ID for " +
3427 str( appName ) + " that apps does." )
3428 elif len( current ) > 1:
3429 # there is more than one app with this ID
3430 result = main.FALSE
3431 # We will log this later in the method
3432 elif not current[0][ 'name' ] == appName:
3433 currentName = current[0][ 'name' ]
3434 result = main.FALSE
3435 main.log.error( "'app-ids' has " + str( currentName ) +
3436 " registered under id:" + str( appID ) +
3437 " but 'apps' has " + str( appName ) )
3438 else:
3439 pass # id and name match!
3440 # now make sure that app-ids has no duplicates
3441 idsList = []
3442 namesList = []
3443 for item in ids:
3444 idsList.append( item[ 'id' ] )
3445 namesList.append( item[ 'name' ] )
3446 if len( idsList ) != len( set( idsList ) ) or\
3447 len( namesList ) != len( set( namesList ) ):
3448 main.log.error( "'app-ids' has some duplicate entries: \n"
3449 + json.dumps( ids,
3450 sort_keys=True,
3451 indent=4,
3452 separators=( ',', ': ' ) ) )
3453 result = main.FALSE
3454 return result
Jon Hallc6793552016-01-19 14:18:37 -08003455 except ( TypeError, ValueError ):
3456 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003457 return main.ERROR
3458 except pexpect.EOF:
3459 main.log.error( self.name + ": EOF exception found" )
3460 main.log.error( self.name + ": " + self.handle.before )
3461 main.cleanup()
3462 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003463 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003464 main.log.exception( self.name + ": Uncaught exception!" )
3465 main.cleanup()
3466 main.exit()
3467
Jon Hallfb760a02015-04-13 15:35:03 -07003468 def getCfg( self, component=None, propName=None, short=False,
3469 jsonFormat=True ):
3470 """
3471 Get configuration settings from onos cli
3472 Optional arguments:
3473 component - Optionally only list configurations for a specific
3474 component. If None, all components with configurations
3475 are displayed. Case Sensitive string.
3476 propName - If component is specified, propName option will show
3477 only this specific configuration from that component.
3478 Case Sensitive string.
3479 jsonFormat - Returns output as json. Note that this will override
3480 the short option
3481 short - Short, less verbose, version of configurations.
3482 This is overridden by the json option
3483 returns:
3484 Output from cli as a string or None on error
3485 """
3486 try:
3487 baseStr = "cfg"
3488 cmdStr = " get"
3489 componentStr = ""
3490 if component:
3491 componentStr += " " + component
3492 if propName:
3493 componentStr += " " + propName
3494 if jsonFormat:
3495 baseStr += " -j"
3496 elif short:
3497 baseStr += " -s"
3498 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003499 assert "Command not found:" not in output, output
3500 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003501 return output
3502 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003503 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003504 return None
3505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
3507 return None
3508 except pexpect.EOF:
3509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
3511 main.cleanup()
3512 main.exit()
3513 except Exception:
3514 main.log.exception( self.name + ": Uncaught exception!" )
3515 main.cleanup()
3516 main.exit()
3517
3518 def setCfg( self, component, propName, value=None, check=True ):
3519 """
3520 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003521 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003522 component - The case sensitive name of the component whose
3523 property is to be set
3524 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003525 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003526 value - The value to set the property to. If None, will unset the
3527 property and revert it to it's default value(if applicable)
3528 check - Boolean, Check whether the option was successfully set this
3529 only applies when a value is given.
3530 returns:
3531 main.TRUE on success or main.FALSE on failure. If check is False,
3532 will return main.TRUE unless there is an error
3533 """
3534 try:
3535 baseStr = "cfg"
3536 cmdStr = " set " + str( component ) + " " + str( propName )
3537 if value is not None:
3538 cmdStr += " " + str( value )
3539 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003540 assert "Command not found:" not in output, output
3541 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003542 if value and check:
3543 results = self.getCfg( component=str( component ),
3544 propName=str( propName ),
3545 jsonFormat=True )
3546 # Check if current value is what we just set
3547 try:
3548 jsonOutput = json.loads( results )
3549 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003550 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003551 main.log.exception( "Error parsing cfg output" )
3552 main.log.error( "output:" + repr( results ) )
3553 return main.FALSE
3554 if current == str( value ):
3555 return main.TRUE
3556 return main.FALSE
3557 return main.TRUE
3558 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003559 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003560 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003561 except ( TypeError, ValueError ):
3562 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003563 return main.FALSE
3564 except pexpect.EOF:
3565 main.log.error( self.name + ": EOF exception found" )
3566 main.log.error( self.name + ": " + self.handle.before )
3567 main.cleanup()
3568 main.exit()
3569 except Exception:
3570 main.log.exception( self.name + ": Uncaught exception!" )
3571 main.cleanup()
3572 main.exit()
3573
Jon Hall390696c2015-05-05 17:13:41 -07003574 def setTestAdd( self, setName, values ):
3575 """
3576 CLI command to add elements to a distributed set.
3577 Arguments:
3578 setName - The name of the set to add to.
3579 values - The value(s) to add to the set, space seperated.
3580 Example usages:
3581 setTestAdd( "set1", "a b c" )
3582 setTestAdd( "set2", "1" )
3583 returns:
3584 main.TRUE on success OR
3585 main.FALSE if elements were already in the set OR
3586 main.ERROR on error
3587 """
3588 try:
3589 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3590 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003591 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003592 try:
3593 # TODO: Maybe make this less hardcoded
3594 # ConsistentMap Exceptions
3595 assert "org.onosproject.store.service" not in output
3596 # Node not leader
3597 assert "java.lang.IllegalStateException" not in output
3598 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003599 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003600 "command: " + str( output ) )
3601 retryTime = 30 # Conservative time, given by Madan
3602 main.log.info( "Waiting " + str( retryTime ) +
3603 "seconds before retrying." )
3604 time.sleep( retryTime ) # Due to change in mastership
3605 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003606 assert "Error executing command" not in output
3607 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3608 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3609 main.log.info( self.name + ": " + output )
3610 if re.search( positiveMatch, output):
3611 return main.TRUE
3612 elif re.search( negativeMatch, output):
3613 return main.FALSE
3614 else:
3615 main.log.error( self.name + ": setTestAdd did not" +
3616 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003617 main.log.debug( self.name + " actual: " + repr( output ) )
3618 return main.ERROR
3619 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003620 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003621 return main.ERROR
3622 except TypeError:
3623 main.log.exception( self.name + ": Object not as expected" )
3624 return main.ERROR
3625 except pexpect.EOF:
3626 main.log.error( self.name + ": EOF exception found" )
3627 main.log.error( self.name + ": " + self.handle.before )
3628 main.cleanup()
3629 main.exit()
3630 except Exception:
3631 main.log.exception( self.name + ": Uncaught exception!" )
3632 main.cleanup()
3633 main.exit()
3634
3635 def setTestRemove( self, setName, values, clear=False, retain=False ):
3636 """
3637 CLI command to remove elements from a distributed set.
3638 Required arguments:
3639 setName - The name of the set to remove from.
3640 values - The value(s) to remove from the set, space seperated.
3641 Optional arguments:
3642 clear - Clear all elements from the set
3643 retain - Retain only the given values. (intersection of the
3644 original set and the given set)
3645 returns:
3646 main.TRUE on success OR
3647 main.FALSE if the set was not changed OR
3648 main.ERROR on error
3649 """
3650 try:
3651 cmdStr = "set-test-remove "
3652 if clear:
3653 cmdStr += "-c " + str( setName )
3654 elif retain:
3655 cmdStr += "-r " + str( setName ) + " " + str( values )
3656 else:
3657 cmdStr += str( setName ) + " " + str( values )
3658 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003659 try:
3660 # TODO: Maybe make this less hardcoded
3661 # ConsistentMap Exceptions
3662 assert "org.onosproject.store.service" not in output
3663 # Node not leader
3664 assert "java.lang.IllegalStateException" not in output
3665 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003666 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003667 "command: " + str( output ) )
3668 retryTime = 30 # Conservative time, given by Madan
3669 main.log.info( "Waiting " + str( retryTime ) +
3670 "seconds before retrying." )
3671 time.sleep( retryTime ) # Due to change in mastership
3672 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003673 assert "Command not found:" not in output, output
3674 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003675 main.log.info( self.name + ": " + output )
3676 if clear:
3677 pattern = "Set " + str( setName ) + " cleared"
3678 if re.search( pattern, output ):
3679 return main.TRUE
3680 elif retain:
3681 positivePattern = str( setName ) + " was pruned to contain " +\
3682 "only elements of set \[(.*)\]"
3683 negativePattern = str( setName ) + " was not changed by " +\
3684 "retaining only elements of the set " +\
3685 "\[(.*)\]"
3686 if re.search( positivePattern, output ):
3687 return main.TRUE
3688 elif re.search( negativePattern, output ):
3689 return main.FALSE
3690 else:
3691 positivePattern = "\[(.*)\] was removed from the set " +\
3692 str( setName )
3693 if ( len( values.split() ) == 1 ):
3694 negativePattern = "\[(.*)\] was not in set " +\
3695 str( setName )
3696 else:
3697 negativePattern = "No element of \[(.*)\] was in set " +\
3698 str( setName )
3699 if re.search( positivePattern, output ):
3700 return main.TRUE
3701 elif re.search( negativePattern, output ):
3702 return main.FALSE
3703 main.log.error( self.name + ": setTestRemove did not" +
3704 " match expected output" )
3705 main.log.debug( self.name + " expected: " + pattern )
3706 main.log.debug( self.name + " actual: " + repr( output ) )
3707 return main.ERROR
3708 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003709 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003710 return main.ERROR
3711 except TypeError:
3712 main.log.exception( self.name + ": Object not as expected" )
3713 return main.ERROR
3714 except pexpect.EOF:
3715 main.log.error( self.name + ": EOF exception found" )
3716 main.log.error( self.name + ": " + self.handle.before )
3717 main.cleanup()
3718 main.exit()
3719 except Exception:
3720 main.log.exception( self.name + ": Uncaught exception!" )
3721 main.cleanup()
3722 main.exit()
3723
3724 def setTestGet( self, setName, values="" ):
3725 """
3726 CLI command to get the elements in a distributed set.
3727 Required arguments:
3728 setName - The name of the set to remove from.
3729 Optional arguments:
3730 values - The value(s) to check if in the set, space seperated.
3731 returns:
3732 main.ERROR on error OR
3733 A list of elements in the set if no optional arguments are
3734 supplied OR
3735 A tuple containing the list then:
3736 main.FALSE if the given values are not in the set OR
3737 main.TRUE if the given values are in the set OR
3738 """
3739 try:
3740 values = str( values ).strip()
3741 setName = str( setName ).strip()
3742 length = len( values.split() )
3743 containsCheck = None
3744 # Patterns to match
3745 setPattern = "\[(.*)\]"
3746 pattern = "Items in set " + setName + ":\n" + setPattern
3747 containsTrue = "Set " + setName + " contains the value " + values
3748 containsFalse = "Set " + setName + " did not contain the value " +\
3749 values
3750 containsAllTrue = "Set " + setName + " contains the the subset " +\
3751 setPattern
3752 containsAllFalse = "Set " + setName + " did not contain the the" +\
3753 " subset " + setPattern
3754
3755 cmdStr = "set-test-get "
3756 cmdStr += setName + " " + values
3757 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003758 try:
3759 # TODO: Maybe make this less hardcoded
3760 # ConsistentMap Exceptions
3761 assert "org.onosproject.store.service" not in output
3762 # Node not leader
3763 assert "java.lang.IllegalStateException" not in output
3764 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003765 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003766 "command: " + str( output ) )
3767 retryTime = 30 # Conservative time, given by Madan
3768 main.log.info( "Waiting " + str( retryTime ) +
3769 "seconds before retrying." )
3770 time.sleep( retryTime ) # Due to change in mastership
3771 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003772 assert "Command not found:" not in output, output
3773 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003774 main.log.info( self.name + ": " + output )
3775
3776 if length == 0:
3777 match = re.search( pattern, output )
3778 else: # if given values
3779 if length == 1: # Contains output
3780 patternTrue = pattern + "\n" + containsTrue
3781 patternFalse = pattern + "\n" + containsFalse
3782 else: # ContainsAll output
3783 patternTrue = pattern + "\n" + containsAllTrue
3784 patternFalse = pattern + "\n" + containsAllFalse
3785 matchTrue = re.search( patternTrue, output )
3786 matchFalse = re.search( patternFalse, output )
3787 if matchTrue:
3788 containsCheck = main.TRUE
3789 match = matchTrue
3790 elif matchFalse:
3791 containsCheck = main.FALSE
3792 match = matchFalse
3793 else:
3794 main.log.error( self.name + " setTestGet did not match " +\
3795 "expected output" )
3796 main.log.debug( self.name + " expected: " + pattern )
3797 main.log.debug( self.name + " actual: " + repr( output ) )
3798 match = None
3799 if match:
3800 setMatch = match.group( 1 )
3801 if setMatch == '':
3802 setList = []
3803 else:
3804 setList = setMatch.split( ", " )
3805 if length > 0:
3806 return ( setList, containsCheck )
3807 else:
3808 return setList
3809 else: # no match
3810 main.log.error( self.name + ": setTestGet did not" +
3811 " match expected output" )
3812 main.log.debug( self.name + " expected: " + pattern )
3813 main.log.debug( self.name + " actual: " + repr( output ) )
3814 return main.ERROR
3815 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003816 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003817 return main.ERROR
3818 except TypeError:
3819 main.log.exception( self.name + ": Object not as expected" )
3820 return main.ERROR
3821 except pexpect.EOF:
3822 main.log.error( self.name + ": EOF exception found" )
3823 main.log.error( self.name + ": " + self.handle.before )
3824 main.cleanup()
3825 main.exit()
3826 except Exception:
3827 main.log.exception( self.name + ": Uncaught exception!" )
3828 main.cleanup()
3829 main.exit()
3830
3831 def setTestSize( self, setName ):
3832 """
3833 CLI command to get the elements in a distributed set.
3834 Required arguments:
3835 setName - The name of the set to remove from.
3836 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003837 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003838 None on error
3839 """
3840 try:
3841 # TODO: Should this check against the number of elements returned
3842 # and then return true/false based on that?
3843 setName = str( setName ).strip()
3844 # Patterns to match
3845 setPattern = "\[(.*)\]"
3846 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3847 setPattern
3848 cmdStr = "set-test-get -s "
3849 cmdStr += setName
3850 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003851 try:
3852 # TODO: Maybe make this less hardcoded
3853 # ConsistentMap Exceptions
3854 assert "org.onosproject.store.service" not in output
3855 # Node not leader
3856 assert "java.lang.IllegalStateException" not in output
3857 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003858 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003859 "command: " + str( output ) )
3860 retryTime = 30 # Conservative time, given by Madan
3861 main.log.info( "Waiting " + str( retryTime ) +
3862 "seconds before retrying." )
3863 time.sleep( retryTime ) # Due to change in mastership
3864 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003865 assert "Command not found:" not in output, output
3866 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003867 main.log.info( self.name + ": " + output )
3868 match = re.search( pattern, output )
3869 if match:
3870 setSize = int( match.group( 1 ) )
3871 setMatch = match.group( 2 )
3872 if len( setMatch.split() ) == setSize:
3873 main.log.info( "The size returned by " + self.name +
3874 " matches the number of elements in " +
3875 "the returned set" )
3876 else:
3877 main.log.error( "The size returned by " + self.name +
3878 " does not match the number of " +
3879 "elements in the returned set." )
3880 return setSize
3881 else: # no match
3882 main.log.error( self.name + ": setTestGet did not" +
3883 " match expected output" )
3884 main.log.debug( self.name + " expected: " + pattern )
3885 main.log.debug( self.name + " actual: " + repr( output ) )
3886 return None
3887 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003888 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003889 return None
Jon Hall390696c2015-05-05 17:13:41 -07003890 except TypeError:
3891 main.log.exception( self.name + ": Object not as expected" )
3892 return None
3893 except pexpect.EOF:
3894 main.log.error( self.name + ": EOF exception found" )
3895 main.log.error( self.name + ": " + self.handle.before )
3896 main.cleanup()
3897 main.exit()
3898 except Exception:
3899 main.log.exception( self.name + ": Uncaught exception!" )
3900 main.cleanup()
3901 main.exit()
3902
Jon Hall80daded2015-05-27 16:07:00 -07003903 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003904 """
3905 Command to list the various counters in the system.
3906 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003907 if jsonFormat, a string of the json object returned by the cli
3908 command
3909 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07003910 None on error
3911 """
Jon Hall390696c2015-05-05 17:13:41 -07003912 try:
3913 counters = {}
3914 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07003915 if jsonFormat:
3916 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07003917 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003918 assert "Command not found:" not in output, output
3919 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003920 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07003921 return output
Jon Hall390696c2015-05-05 17:13:41 -07003922 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003923 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07003924 return None
Jon Hall390696c2015-05-05 17:13:41 -07003925 except TypeError:
3926 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07003927 return None
Jon Hall390696c2015-05-05 17:13:41 -07003928 except pexpect.EOF:
3929 main.log.error( self.name + ": EOF exception found" )
3930 main.log.error( self.name + ": " + self.handle.before )
3931 main.cleanup()
3932 main.exit()
3933 except Exception:
3934 main.log.exception( self.name + ": Uncaught exception!" )
3935 main.cleanup()
3936 main.exit()
3937
Jon Halle1a3b752015-07-22 13:02:46 -07003938 def counterTestAddAndGet( self, counter, delta=1, inMemory=False ):
Jon Hall390696c2015-05-05 17:13:41 -07003939 """
Jon Halle1a3b752015-07-22 13:02:46 -07003940 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07003941 Required arguments:
3942 counter - The name of the counter to increment.
3943 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07003944 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07003945 inMemory - use in memory map for the counter
3946 returns:
3947 integer value of the counter or
3948 None on Error
3949 """
3950 try:
3951 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07003952 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003953 cmdStr = "counter-test-increment "
3954 if inMemory:
3955 cmdStr += "-i "
3956 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07003957 if delta != 1:
3958 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07003959 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003960 try:
3961 # TODO: Maybe make this less hardcoded
3962 # ConsistentMap Exceptions
3963 assert "org.onosproject.store.service" not in output
3964 # Node not leader
3965 assert "java.lang.IllegalStateException" not in output
3966 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003967 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003968 "command: " + str( output ) )
3969 retryTime = 30 # Conservative time, given by Madan
3970 main.log.info( "Waiting " + str( retryTime ) +
3971 "seconds before retrying." )
3972 time.sleep( retryTime ) # Due to change in mastership
3973 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003974 assert "Command not found:" not in output, output
3975 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003976 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07003977 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07003978 match = re.search( pattern, output )
3979 if match:
3980 return int( match.group( 1 ) )
3981 else:
Jon Halle1a3b752015-07-22 13:02:46 -07003982 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07003983 " match expected output." )
3984 main.log.debug( self.name + " expected: " + pattern )
3985 main.log.debug( self.name + " actual: " + repr( output ) )
3986 return None
3987 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003988 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003989 return None
3990 except TypeError:
3991 main.log.exception( self.name + ": Object not as expected" )
3992 return None
3993 except pexpect.EOF:
3994 main.log.error( self.name + ": EOF exception found" )
3995 main.log.error( self.name + ": " + self.handle.before )
3996 main.cleanup()
3997 main.exit()
3998 except Exception:
3999 main.log.exception( self.name + ": Uncaught exception!" )
4000 main.cleanup()
4001 main.exit()
4002
Jon Halle1a3b752015-07-22 13:02:46 -07004003 def counterTestGetAndAdd( self, counter, delta=1, inMemory=False ):
4004 """
4005 CLI command to get a distributed counter then add a delta to it.
4006 Required arguments:
4007 counter - The name of the counter to increment.
4008 Optional arguments:
4009 delta - The long to add to the counter
4010 inMemory - use in memory map for the counter
4011 returns:
4012 integer value of the counter or
4013 None on Error
4014 """
4015 try:
4016 counter = str( counter )
4017 delta = int( delta )
4018 cmdStr = "counter-test-increment -g "
4019 if inMemory:
4020 cmdStr += "-i "
4021 cmdStr += counter
4022 if delta != 1:
4023 cmdStr += " " + str( delta )
4024 output = self.sendline( cmdStr )
4025 try:
4026 # TODO: Maybe make this less hardcoded
4027 # ConsistentMap Exceptions
4028 assert "org.onosproject.store.service" not in output
4029 # Node not leader
4030 assert "java.lang.IllegalStateException" not in output
4031 except AssertionError:
4032 main.log.error( "Error in processing '" + cmdStr + "' " +
4033 "command: " + str( output ) )
4034 retryTime = 30 # Conservative time, given by Madan
4035 main.log.info( "Waiting " + str( retryTime ) +
4036 "seconds before retrying." )
4037 time.sleep( retryTime ) # Due to change in mastership
4038 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004039 assert "Command not found:" not in output, output
4040 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004041 main.log.info( self.name + ": " + output )
4042 pattern = counter + " was updated to (-?\d+)"
4043 match = re.search( pattern, output )
4044 if match:
4045 return int( match.group( 1 ) )
4046 else:
4047 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4048 " match expected output." )
4049 main.log.debug( self.name + " expected: " + pattern )
4050 main.log.debug( self.name + " actual: " + repr( output ) )
4051 return None
4052 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004053 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004054 return None
4055 except TypeError:
4056 main.log.exception( self.name + ": Object not as expected" )
4057 return None
4058 except pexpect.EOF:
4059 main.log.error( self.name + ": EOF exception found" )
4060 main.log.error( self.name + ": " + self.handle.before )
4061 main.cleanup()
4062 main.exit()
4063 except Exception:
4064 main.log.exception( self.name + ": Uncaught exception!" )
4065 main.cleanup()
4066 main.exit()
4067
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004068 def summary( self, jsonFormat=True ):
4069 """
4070 Description: Execute summary command in onos
4071 Returns: json object ( summary -j ), returns main.FALSE if there is
4072 no output
4073
4074 """
4075 try:
4076 cmdStr = "summary"
4077 if jsonFormat:
4078 cmdStr += " -j"
4079 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004080 assert "Command not found:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004081 if re.search( "Error:", handle ):
4082 main.log.error( self.name + ": summary() response: " +
4083 str( handle ) )
4084 if not handle:
4085 main.log.error( self.name + ": There is no output in " +
4086 "summary command" )
4087 return main.FALSE
4088 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004089 except AssertionError:
4090 main.log.exception( "" )
4091 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004092 except TypeError:
4093 main.log.exception( self.name + ": Object not as expected" )
4094 return None
4095 except pexpect.EOF:
4096 main.log.error( self.name + ": EOF exception found" )
4097 main.log.error( self.name + ": " + self.handle.before )
4098 main.cleanup()
4099 main.exit()
4100 except Exception:
4101 main.log.exception( self.name + ": Uncaught exception!" )
4102 main.cleanup()
4103 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004104
4105 def transactionalMapGet( self, keyName, inMemory=False ):
4106 """
4107 CLI command to get the value of a key in a consistent map using
4108 transactions. This a test function and can only get keys from the
4109 test map hard coded into the cli command
4110 Required arguments:
4111 keyName - The name of the key to get
4112 Optional arguments:
4113 inMemory - use in memory map for the counter
4114 returns:
4115 The string value of the key or
4116 None on Error
4117 """
4118 try:
4119 keyName = str( keyName )
4120 cmdStr = "transactional-map-test-get "
4121 if inMemory:
4122 cmdStr += "-i "
4123 cmdStr += keyName
4124 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004125 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004126 try:
4127 # TODO: Maybe make this less hardcoded
4128 # ConsistentMap Exceptions
4129 assert "org.onosproject.store.service" not in output
4130 # Node not leader
4131 assert "java.lang.IllegalStateException" not in output
4132 except AssertionError:
4133 main.log.error( "Error in processing '" + cmdStr + "' " +
4134 "command: " + str( output ) )
4135 return None
4136 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4137 if "Key " + keyName + " not found." in output:
4138 return None
4139 else:
4140 match = re.search( pattern, output )
4141 if match:
4142 return match.groupdict()[ 'value' ]
4143 else:
4144 main.log.error( self.name + ": transactionlMapGet did not" +
4145 " match expected output." )
4146 main.log.debug( self.name + " expected: " + pattern )
4147 main.log.debug( self.name + " actual: " + repr( output ) )
4148 return None
Jon Hallc6793552016-01-19 14:18:37 -08004149 except AssertionError:
4150 main.log.exception( "" )
4151 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004152 except TypeError:
4153 main.log.exception( self.name + ": Object not as expected" )
4154 return None
4155 except pexpect.EOF:
4156 main.log.error( self.name + ": EOF exception found" )
4157 main.log.error( self.name + ": " + self.handle.before )
4158 main.cleanup()
4159 main.exit()
4160 except Exception:
4161 main.log.exception( self.name + ": Uncaught exception!" )
4162 main.cleanup()
4163 main.exit()
4164
4165 def transactionalMapPut( self, numKeys, value, inMemory=False ):
4166 """
4167 CLI command to put a value into 'numKeys' number of keys in a
4168 consistent map using transactions. This a test function and can only
4169 put into keys named 'Key#' of the test map hard coded into the cli command
4170 Required arguments:
4171 numKeys - Number of keys to add the value to
4172 value - The string value to put into the keys
4173 Optional arguments:
4174 inMemory - use in memory map for the counter
4175 returns:
4176 A dictionary whose keys are the name of the keys put into the map
4177 and the values of the keys are dictionaries whose key-values are
4178 'value': value put into map and optionaly
4179 'oldValue': Previous value in the key or
4180 None on Error
4181
4182 Example output
4183 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4184 'Key2': {'value': 'Testing'} }
4185 """
4186 try:
4187 numKeys = str( numKeys )
4188 value = str( value )
4189 cmdStr = "transactional-map-test-put "
4190 if inMemory:
4191 cmdStr += "-i "
4192 cmdStr += numKeys + " " + value
4193 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004194 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004195 try:
4196 # TODO: Maybe make this less hardcoded
4197 # ConsistentMap Exceptions
4198 assert "org.onosproject.store.service" not in output
4199 # Node not leader
4200 assert "java.lang.IllegalStateException" not in output
4201 except AssertionError:
4202 main.log.error( "Error in processing '" + cmdStr + "' " +
4203 "command: " + str( output ) )
4204 return None
4205 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4206 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4207 results = {}
4208 for line in output.splitlines():
4209 new = re.search( newPattern, line )
4210 updated = re.search( updatedPattern, line )
4211 if new:
4212 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4213 elif updated:
4214 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004215 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004216 else:
4217 main.log.error( self.name + ": transactionlMapGet did not" +
4218 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004219 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4220 newPattern,
4221 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004222 main.log.debug( self.name + " actual: " + repr( output ) )
4223 return results
Jon Hallc6793552016-01-19 14:18:37 -08004224 except AssertionError:
4225 main.log.exception( "" )
4226 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004227 except TypeError:
4228 main.log.exception( self.name + ": Object not as expected" )
4229 return None
4230 except pexpect.EOF:
4231 main.log.error( self.name + ": EOF exception found" )
4232 main.log.error( self.name + ": " + self.handle.before )
4233 main.cleanup()
4234 main.exit()
4235 except Exception:
4236 main.log.exception( self.name + ": Uncaught exception!" )
4237 main.cleanup()
4238 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004239
acsmarsdaea66c2015-09-03 11:44:06 -07004240 def maps( self, jsonFormat=True ):
4241 """
4242 Description: Returns result of onos:maps
4243 Optional:
4244 * jsonFormat: enable json formatting of output
4245 """
4246 try:
4247 cmdStr = "maps"
4248 if jsonFormat:
4249 cmdStr += " -j"
4250 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004251 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004252 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004253 except AssertionError:
4254 main.log.exception( "" )
4255 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004256 except TypeError:
4257 main.log.exception( self.name + ": Object not as expected" )
4258 return None
4259 except pexpect.EOF:
4260 main.log.error( self.name + ": EOF exception found" )
4261 main.log.error( self.name + ": " + self.handle.before )
4262 main.cleanup()
4263 main.exit()
4264 except Exception:
4265 main.log.exception( self.name + ": Uncaught exception!" )
4266 main.cleanup()
4267 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004268
4269 def getSwController( self, uri, jsonFormat=True ):
4270 """
4271 Descrition: Gets the controller information from the device
4272 """
4273 try:
4274 cmd = "device-controllers "
4275 if jsonFormat:
4276 cmd += "-j "
4277 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004278 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004279 return response
Jon Hallc6793552016-01-19 14:18:37 -08004280 except AssertionError:
4281 main.log.exception( "" )
4282 return None
GlennRC050596c2015-11-18 17:06:41 -08004283 except TypeError:
4284 main.log.exception( self.name + ": Object not as expected" )
4285 return None
4286 except pexpect.EOF:
4287 main.log.error( self.name + ": EOF exception found" )
4288 main.log.error( self.name + ": " + self.handle.before )
4289 main.cleanup()
4290 main.exit()
4291 except Exception:
4292 main.log.exception( self.name + ": Uncaught exception!" )
4293 main.cleanup()
4294 main.exit()
4295
4296 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4297 """
4298 Descrition: sets the controller(s) for the specified device
4299
4300 Parameters:
4301 Required: uri - String: The uri of the device(switch).
4302 ip - String or List: The ip address of the controller.
4303 This parameter can be formed in a couple of different ways.
4304 VALID:
4305 10.0.0.1 - just the ip address
4306 tcp:10.0.0.1 - the protocol and the ip address
4307 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4308 so that you can add controllers with different
4309 protocols and ports
4310 INVALID:
4311 10.0.0.1:6653 - this is not supported by ONOS
4312
4313 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4314 port - The port number.
4315 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4316
4317 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4318 """
4319 try:
4320 cmd = "device-setcontrollers"
4321
4322 if jsonFormat:
4323 cmd += " -j"
4324 cmd += " " + uri
4325 if isinstance( ip, str ):
4326 ip = [ip]
4327 for item in ip:
4328 if ":" in item:
4329 sitem = item.split( ":" )
4330 if len(sitem) == 3:
4331 cmd += " " + item
4332 elif "." in sitem[1]:
4333 cmd += " {}:{}".format(item, port)
4334 else:
4335 main.log.error( "Malformed entry: " + item )
4336 raise TypeError
4337 else:
4338 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004339 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004340 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004341 if "Error" in response:
4342 main.log.error( response )
4343 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004344 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004345 except AssertionError:
4346 main.log.exception( "" )
4347 return None
GlennRC050596c2015-11-18 17:06:41 -08004348 except TypeError:
4349 main.log.exception( self.name + ": Object not as expected" )
4350 return main.FALSE
4351 except pexpect.EOF:
4352 main.log.error( self.name + ": EOF exception found" )
4353 main.log.error( self.name + ": " + self.handle.before )
4354 main.cleanup()
4355 main.exit()
4356 except Exception:
4357 main.log.exception( self.name + ": Uncaught exception!" )
4358 main.cleanup()
4359 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004360
4361 def removeDevice( self, device ):
4362 '''
4363 Description:
4364 Remove a device from ONOS by passing the uri of the device(s).
4365 Parameters:
4366 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4367 Returns:
4368 Returns main.FALSE if an exception is thrown or an error is present
4369 in the response. Otherwise, returns main.TRUE.
4370 NOTE:
4371 If a host cannot be removed, then this function will return main.FALSE
4372 '''
4373 try:
4374 if type( device ) is str:
4375 device = list( device )
4376
4377 for d in device:
4378 time.sleep( 1 )
4379 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004380 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004381 if "Error" in response:
4382 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4383 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004384 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004385 except AssertionError:
4386 main.log.exception( "" )
4387 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004388 except TypeError:
4389 main.log.exception( self.name + ": Object not as expected" )
4390 return main.FALSE
4391 except pexpect.EOF:
4392 main.log.error( self.name + ": EOF exception found" )
4393 main.log.error( self.name + ": " + self.handle.before )
4394 main.cleanup()
4395 main.exit()
4396 except Exception:
4397 main.log.exception( self.name + ": Uncaught exception!" )
4398 main.cleanup()
4399 main.exit()
4400
4401 def removeHost( self, host ):
4402 '''
4403 Description:
4404 Remove a host from ONOS by passing the id of the host(s)
4405 Parameters:
4406 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4407 Returns:
4408 Returns main.FALSE if an exception is thrown or an error is present
4409 in the response. Otherwise, returns main.TRUE.
4410 NOTE:
4411 If a host cannot be removed, then this function will return main.FALSE
4412 '''
4413 try:
4414 if type( host ) is str:
4415 host = list( host )
4416
4417 for h in host:
4418 time.sleep( 1 )
4419 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004420 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004421 if "Error" in response:
4422 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4423 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004424 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004425 except AssertionError:
4426 main.log.exception( "" )
4427 return None
GlennRC20fc6522015-12-23 23:26:57 -08004428 except TypeError:
4429 main.log.exception( self.name + ": Object not as expected" )
4430 return main.FALSE
4431 except pexpect.EOF:
4432 main.log.error( self.name + ": EOF exception found" )
4433 main.log.error( self.name + ": " + self.handle.before )
4434 main.cleanup()
4435 main.exit()
4436 except Exception:
4437 main.log.exception( self.name + ": Uncaught exception!" )
4438 main.cleanup()
4439 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004440
Jon Hallc6793552016-01-19 14:18:37 -08004441 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004442 '''
4443 Description:
4444 Bring link down or up in the null-provider.
4445 params:
4446 begin - (string) One end of a device or switch.
4447 end - (string) the other end of the device or switch
4448 returns:
4449 main.TRUE if no exceptions were thrown and no Errors are
4450 present in the resoponse. Otherwise, returns main.FALSE
4451 '''
4452 try:
Jon Hallc6793552016-01-19 14:18:37 -08004453 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004454 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004455 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004456 if "Error" in response or "Failure" in response:
4457 main.log.error( response )
4458 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004459 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004460 except AssertionError:
4461 main.log.exception( "" )
4462 return None
GlennRCed771242016-01-13 17:02:47 -08004463 except TypeError:
4464 main.log.exception( self.name + ": Object not as expected" )
4465 return main.FALSE
4466 except pexpect.EOF:
4467 main.log.error( self.name + ": EOF exception found" )
4468 main.log.error( self.name + ": " + self.handle.before )
4469 main.cleanup()
4470 main.exit()
4471 except Exception:
4472 main.log.exception( self.name + ": Uncaught exception!" )
4473 main.cleanup()
4474 main.exit()
4475