blob: e1d298a3d250903ac1dd2ea0cffce1afc8822276 [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" )
Jon Hallbfe00002016-04-05 10:23:54 -0700145 j = self.handle.expect( [ "\$",
146 "Command not found:",
147 pexpect.TIMEOUT ] )
148 if j == 0: # Successfully logged out
149 return main.TRUE
150 elif j == 1 or j == 2:
151 # ONOS didn't fully load, and logout command isn't working
152 # or the command timed out
153 self.handle.send( "\x04" ) # send ctrl-d
154 self.handle.expect( "\$" )
155 return main.TRUE
156 else: # some other output
157 main.log.warn( "Unknown repsonse to logout command: '{}'",
158 repr( self.handle.before ) )
159 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700160 elif i == 1: # not in CLI
161 return main.TRUE
162 elif i == 3: # Timeout
163 return main.FALSE
164 else:
andrewonlab9627f432014-11-14 12:45:10 -0500165 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800166 except TypeError:
167 main.log.exception( self.name + ": Object not as expected" )
168 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500169 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800170 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700171 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 main.cleanup()
173 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700174 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700175 main.log.error( self.name +
176 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800177 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800178 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 main.cleanup()
180 main.exit()
181
kelvin-onlabd3b64892015-01-20 13:26:24 -0800182 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800183 """
andrewonlab95ce8322014-10-13 14:12:04 -0400184 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800185
andrewonlab95ce8322014-10-13 14:12:04 -0400186 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800187 """
andrewonlab95ce8322014-10-13 14:12:04 -0400188 try:
189 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800190 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400191 main.cleanup()
192 main.exit()
193 else:
kelvin8ec71442015-01-15 16:57:00 -0800194 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800195 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800196 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400197 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800198 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800199 handleBefore = self.handle.before
200 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800201 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800202 self.handle.sendline("")
203 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800204 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400205
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 main.log.info( "Cell call returned: " + handleBefore +
207 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400208
209 return main.TRUE
210
Jon Halld4d4b372015-01-28 16:02:41 -0800211 except TypeError:
212 main.log.exception( self.name + ": Object not as expected" )
213 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400214 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800215 main.log.error( self.name + ": eof exception found" )
216 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400217 main.cleanup()
218 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800220 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400221 main.cleanup()
222 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800223
pingping-lin57a56ce2015-05-20 16:43:48 -0700224 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800225 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800226 """
Jon Hallefbd9792015-03-05 16:11:36 -0800227 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 by user would be used to set the current karaf shell idle timeout.
229 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800230 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 Below is an example to start a session with 60 seconds idle timeout
232 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800233
Hari Krishna25d42f72015-01-05 15:08:28 -0800234 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800235 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800236
kelvin-onlabd3b64892015-01-20 13:26:24 -0800237 Note: karafTimeout is left as str so that this could be read
238 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800239 """
You Wangf69ab392016-01-26 16:34:38 -0800240 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400241 try:
kelvin8ec71442015-01-15 16:57:00 -0800242 self.handle.sendline( "" )
243 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700244 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500245
246 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800247 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500248 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400249
kelvin8ec71442015-01-15 16:57:00 -0800250 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800251 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800252 i = self.handle.expect( [
253 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400255
256 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800257 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800258 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800259 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800260 "config:property-set -p org.apache.karaf.shell\
261 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800262 karafTimeout )
263 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800265 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400266 return main.TRUE
267 else:
kelvin8ec71442015-01-15 16:57:00 -0800268 # If failed, send ctrl+c to process and try again
269 main.log.info( "Starting CLI failed. Retrying..." )
270 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800272 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
273 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400274 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800275 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800276 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800277 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800278 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800279 "config:property-set -p org.apache.karaf.shell\
280 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800281 karafTimeout )
282 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800283 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800284 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400285 return main.TRUE
286 else:
kelvin8ec71442015-01-15 16:57:00 -0800287 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800288 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400290
Jon Halld4d4b372015-01-28 16:02:41 -0800291 except TypeError:
292 main.log.exception( self.name + ": Object not as expected" )
293 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400294 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800295 main.log.error( self.name + ": EOF exception found" )
296 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400297 main.cleanup()
298 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800300 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400301 main.cleanup()
302 main.exit()
303
Jon Hallefbd9792015-03-05 16:11:36 -0800304 def log( self, cmdStr, level="" ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800305 """
306 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800307 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800308 returns main.FALSE if Error occurred
kelvin-onlab338f5512015-02-06 10:53:16 -0800309 Available level: DEBUG, TRACE, INFO, WARN, ERROR
310 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800311 """
312 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800313 lvlStr = ""
314 if level:
315 lvlStr = "--level=" + level
316
kelvin-onlab9f541032015-02-04 16:19:53 -0800317 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800318 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700319 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800320 main.log.error( self.name + ": onos cli session closed. ")
321 if self.onosIp:
322 main.log.warn( "Trying to reconnect " + self.onosIp )
323 reconnectResult = self.startOnosCli( self.onosIp )
324 if reconnectResult:
325 main.log.info( self.name + ": onos cli session reconnected." )
326 else:
327 main.log.error( self.name + ": reconnection failed." )
328 main.cleanup()
329 main.exit()
330 else:
331 main.cleanup()
332 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700333 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700334 self.handle.sendline( "" )
335 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800336 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700337 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800338 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800339
kelvin-onlab9f541032015-02-04 16:19:53 -0800340 response = self.handle.before
341 if re.search( "Error", response ):
342 return main.FALSE
343 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700344 except pexpect.TIMEOUT:
345 main.log.exception( self.name + ": TIMEOUT exception found" )
346 main.cleanup()
347 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800348 except pexpect.EOF:
349 main.log.error( self.name + ": EOF exception found" )
350 main.log.error( self.name + ": " + self.handle.before )
351 main.cleanup()
352 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800353 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800354 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400355 main.cleanup()
356 main.exit()
357
GlennRCed771242016-01-13 17:02:47 -0800358 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10 ):
kelvin8ec71442015-01-15 16:57:00 -0800359 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800360 Send a completely user specified string to
361 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400362 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800363
andrewonlaba18f6bf2014-10-13 19:31:54 -0400364 Warning: There are no sanity checking to commands
365 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800366
kelvin8ec71442015-01-15 16:57:00 -0800367 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400368 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800369 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
370 self.log( logStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800371 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800372 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800373 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800374 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800375 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
376 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700377 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700378 main.log.debug( self.name + ": Raw output" )
379 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700380
381 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800382 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800383 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700384 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700385 main.log.debug( self.name + ": ansiEscape output" )
386 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700387
kelvin-onlabfb521662015-02-27 09:52:40 -0800388 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800389 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700390 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700391 main.log.debug( self.name + ": Removed extra returns " +
392 "from output" )
393 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700394
395 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800396 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700397 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700398 main.log.debug( self.name + ": parsed and stripped output" )
399 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700400
Jon Hall63604932015-02-26 17:09:50 -0800401 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700402 output = response.split( cmdStr.strip(), 1 )
403 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700404 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700405 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700406 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800407 output = output[1].strip()
408 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800409 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800410 return output
GlennRCed771242016-01-13 17:02:47 -0800411 except pexpect.TIMEOUT:
412 main.log.error( self.name + ":ONOS timeout" )
413 if debug:
414 main.log.debug( self.handle.before )
415 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700416 except IndexError:
417 main.log.exception( self.name + ": Object not as expected" )
418 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800419 except TypeError:
420 main.log.exception( self.name + ": Object not as expected" )
421 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400422 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800423 main.log.error( self.name + ": EOF exception found" )
424 main.log.error( self.name + ": " + self.handle.before )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400425 main.cleanup()
426 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800427 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800428 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlaba18f6bf2014-10-13 19:31:54 -0400429 main.cleanup()
430 main.exit()
431
kelvin8ec71442015-01-15 16:57:00 -0800432 # IMPORTANT NOTE:
433 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800434 # the cli command changing 'a:b' with 'aB'.
435 # Ex ) onos:topology > onosTopology
436 # onos:links > onosLinks
437 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800438
kelvin-onlabd3b64892015-01-20 13:26:24 -0800439 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800440 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400441 Adds a new cluster node by ID and address information.
442 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800443 * nodeId
444 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400445 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800446 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800447 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400448 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800449 cmdStr = "add-node " + str( nodeId ) + " " +\
450 str( ONOSIp ) + " " + str( tcpPort )
451 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800452 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800453 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800454 main.log.error( "Error in adding node" )
455 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800456 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400457 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800458 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400459 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800460 except AssertionError:
461 main.log.exception( "" )
462 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800463 except TypeError:
464 main.log.exception( self.name + ": Object not as expected" )
465 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400466 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800467 main.log.error( self.name + ": EOF exception found" )
468 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400469 main.cleanup()
470 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800472 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400473 main.cleanup()
474 main.exit()
475
kelvin-onlabd3b64892015-01-20 13:26:24 -0800476 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800477 """
andrewonlab86dc3082014-10-13 18:18:38 -0400478 Removes a cluster by ID
479 Issues command: 'remove-node [<node-id>]'
480 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800482 """
andrewonlab86dc3082014-10-13 18:18:38 -0400483 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400484
kelvin-onlabd3b64892015-01-20 13:26:24 -0800485 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700486 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800487 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 if re.search( "Error", handle ):
489 main.log.error( "Error in removing node" )
490 main.log.error( handle )
491 return main.FALSE
492 else:
493 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800494 except AssertionError:
495 main.log.exception( "" )
496 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800497 except TypeError:
498 main.log.exception( self.name + ": Object not as expected" )
499 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400500 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800501 main.log.error( self.name + ": EOF exception found" )
502 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400503 main.cleanup()
504 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800505 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800506 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400507 main.cleanup()
508 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400509
Jon Hall61282e32015-03-19 11:34:11 -0700510 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800511 """
andrewonlab7c211572014-10-15 16:45:20 -0400512 List the nodes currently visible
513 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700514 Optional argument:
515 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800516 """
andrewonlab7c211572014-10-15 16:45:20 -0400517 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700519 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700520 cmdStr += " -j"
521 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800522 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 return output
Jon Hallc6793552016-01-19 14:18:37 -0800524 except AssertionError:
525 main.log.exception( "" )
526 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800527 except TypeError:
528 main.log.exception( self.name + ": Object not as expected" )
529 return None
andrewonlab7c211572014-10-15 16:45:20 -0400530 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800531 main.log.error( self.name + ": EOF exception found" )
532 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400533 main.cleanup()
534 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800536 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400537 main.cleanup()
538 main.exit()
539
kelvin8ec71442015-01-15 16:57:00 -0800540 def topology( self ):
541 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700542 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700543 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700544 Return:
545 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800546 """
andrewonlab95ce8322014-10-13 14:12:04 -0400547 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700548 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800549 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800550 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700551 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400552 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800553 except AssertionError:
554 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800555 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800556 except TypeError:
557 main.log.exception( self.name + ": Object not as expected" )
558 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( self.name + ": EOF exception found" )
561 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400562 main.cleanup()
563 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800564 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800565 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400566 main.cleanup()
567 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800568
jenkins7ead5a82015-03-13 10:28:21 -0700569 def deviceRemove( self, deviceId ):
570 """
571 Removes particular device from storage
572
573 TODO: refactor this function
574 """
575 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 cmdStr = "device-remove " + str( deviceId )
577 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800578 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700579 if re.search( "Error", handle ):
580 main.log.error( "Error in removing device" )
581 main.log.error( handle )
582 return main.FALSE
583 else:
584 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800585 except AssertionError:
586 main.log.exception( "" )
587 return None
jenkins7ead5a82015-03-13 10:28:21 -0700588 except TypeError:
589 main.log.exception( self.name + ": Object not as expected" )
590 return None
591 except pexpect.EOF:
592 main.log.error( self.name + ": EOF exception found" )
593 main.log.error( self.name + ": " + self.handle.before )
594 main.cleanup()
595 main.exit()
596 except Exception:
597 main.log.exception( self.name + ": Uncaught exception!" )
598 main.cleanup()
599 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700600
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800602 """
Jon Hall7b02d952014-10-17 20:14:54 -0400603 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400604 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800606 """
andrewonlab86dc3082014-10-13 18:18:38 -0400607 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700608 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800609 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700610 cmdStr += " -j"
611 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800612 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700613 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800614 except AssertionError:
615 main.log.exception( "" )
616 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800617 except TypeError:
618 main.log.exception( self.name + ": Object not as expected" )
619 return None
andrewonlab7c211572014-10-15 16:45:20 -0400620 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800621 main.log.error( self.name + ": EOF exception found" )
622 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400623 main.cleanup()
624 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800625 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800626 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400627 main.cleanup()
628 main.exit()
629
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800631 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800632 This balances the devices across all controllers
633 by issuing command: 'onos> onos:balance-masters'
634 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800635 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800636 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800637 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700638 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800639 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700640 if re.search( "Error", handle ):
641 main.log.error( "Error in balancing masters" )
642 main.log.error( handle )
643 return main.FALSE
644 else:
645 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800646 except AssertionError:
647 main.log.exception( "" )
648 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800649 except TypeError:
650 main.log.exception( self.name + ": Object not as expected" )
651 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800652 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800653 main.log.error( self.name + ": EOF exception found" )
654 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800655 main.cleanup()
656 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800658 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800659 main.cleanup()
660 main.exit()
661
Jon Hallc6793552016-01-19 14:18:37 -0800662 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700663 """
664 Returns the output of the masters command.
665 Optional argument:
666 * jsonFormat - boolean indicating if you want output in json
667 """
668 try:
669 cmdStr = "onos:masters"
670 if jsonFormat:
671 cmdStr += " -j"
672 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800673 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700674 return output
Jon Hallc6793552016-01-19 14:18:37 -0800675 except AssertionError:
676 main.log.exception( "" )
677 return None
acsmars24950022015-07-30 18:00:43 -0700678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
681 except pexpect.EOF:
682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
684 main.cleanup()
685 main.exit()
686 except Exception:
687 main.log.exception( self.name + ": Uncaught exception!" )
688 main.cleanup()
689 main.exit()
690
Jon Hallc6793552016-01-19 14:18:37 -0800691 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700692 """
693 Uses the master command to check that the devices' leadership
694 is evenly divided
695
696 Dependencies: checkMasters() and summary()
697
698 Returns main.True if the devices are balanced
699 Returns main.False if the devices are unbalanced
700 Exits on Exception
701 Returns None on TypeError
702 """
703 try:
Jon Hallc6793552016-01-19 14:18:37 -0800704 summaryOutput = self.summary()
705 totalDevices = json.loads( summaryOutput )[ "devices" ]
706 except ( TypeError, ValueError ):
707 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
708 return None
709 try:
acsmars24950022015-07-30 18:00:43 -0700710 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800711 mastersOutput = self.checkMasters()
712 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700713 first = masters[ 0 ][ "size" ]
714 for master in masters:
715 totalOwnedDevices += master[ "size" ]
716 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
717 main.log.error( "Mastership not balanced" )
718 main.log.info( "\n" + self.checkMasters( False ) )
719 return main.FALSE
720 main.log.info( "Mastership balanced between " \
721 + str( len(masters) ) + " masters" )
722 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800723 except ( TypeError, ValueError ):
724 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700725 return None
726 except pexpect.EOF:
727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
729 main.cleanup()
730 main.exit()
731 except Exception:
732 main.log.exception( self.name + ": Uncaught exception!" )
733 main.cleanup()
734 main.exit()
735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800737 """
Jon Halle8217482014-10-17 13:49:14 -0400738 Lists all core links
739 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Jon Halle8217482014-10-17 13:49:14 -0400742 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700743 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 cmdStr += " -j"
746 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800747 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800749 except AssertionError:
750 main.log.exception( "" )
751 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800752 except TypeError:
753 main.log.exception( self.name + ": Object not as expected" )
754 return None
Jon Halle8217482014-10-17 13:49:14 -0400755 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800756 main.log.error( self.name + ": EOF exception found" )
757 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400758 main.cleanup()
759 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800761 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400762 main.cleanup()
763 main.exit()
764
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800766 """
Jon Halle8217482014-10-17 13:49:14 -0400767 Lists all ports
768 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800770 """
Jon Halle8217482014-10-17 13:49:14 -0400771 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 cmdStr += " -j"
775 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800776 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800778 except AssertionError:
779 main.log.exception( "" )
780 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800781 except TypeError:
782 main.log.exception( self.name + ": Object not as expected" )
783 return None
Jon Halle8217482014-10-17 13:49:14 -0400784 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800785 main.log.error( self.name + ": EOF exception found" )
786 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400787 main.cleanup()
788 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800789 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800790 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400791 main.cleanup()
792 main.exit()
793
kelvin-onlabd3b64892015-01-20 13:26:24 -0800794 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800795 """
Jon Hall983a1702014-10-28 18:44:22 -0400796 Lists all devices and the controllers with roles assigned to them
797 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800799 """
andrewonlab7c211572014-10-15 16:45:20 -0400800 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700801 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700803 cmdStr += " -j"
804 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800805 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800807 except AssertionError:
808 main.log.exception( "" )
809 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800810 except TypeError:
811 main.log.exception( self.name + ": Object not as expected" )
812 return None
Jon Hall983a1702014-10-28 18:44:22 -0400813 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800814 main.log.error( self.name + ": EOF exception found" )
815 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400816 main.cleanup()
817 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800818 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800819 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400820 main.cleanup()
821 main.exit()
822
kelvin-onlabd3b64892015-01-20 13:26:24 -0800823 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800824 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800825 Given the a string containing the json representation of the "roles"
826 cli command and a partial or whole device id, returns a json object
827 containing the roles output for the first device whose id contains
828 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400829
830 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800831 A dict of the role assignments for the given device or
832 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800833 """
Jon Hall983a1702014-10-28 18:44:22 -0400834 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800835 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400836 return None
837 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800838 rawRoles = self.roles()
839 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800840 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800841 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800842 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800843 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400844 return device
845 return None
Jon Hallc6793552016-01-19 14:18:37 -0800846 except ( TypeError, ValueError ):
847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800848 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400852 main.cleanup()
853 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800855 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400856 main.cleanup()
857 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800858
kelvin-onlabd3b64892015-01-20 13:26:24 -0800859 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Hall94fd0472014-12-08 11:52:42 -0800861 Iterates through each device and checks if there is a master assigned
862 Returns: main.TRUE if each device has a master
863 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800864 """
Jon Hall94fd0472014-12-08 11:52:42 -0800865 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800866 rawRoles = self.roles()
867 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800868 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800870 # print device
871 if device[ 'master' ] == "none":
872 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800873 return main.FALSE
874 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800875 except ( TypeError, ValueError ):
876 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800877 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400890 Returns string of paths, and the cost.
891 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800892 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
895 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800896 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -0800897 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800898 main.log.error( "Error in getting paths" )
899 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400900 else:
kelvin8ec71442015-01-15 16:57:00 -0800901 path = handle.split( ";" )[ 0 ]
902 cost = handle.split( ";" )[ 1 ]
903 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -0800904 except AssertionError:
905 main.log.exception( "" )
906 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -0800907 except TypeError:
908 main.log.exception( self.name + ": Object not as expected" )
909 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -0400913 main.cleanup()
914 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800915 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800916 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -0400917 main.cleanup()
918 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800919
kelvin-onlabd3b64892015-01-20 13:26:24 -0800920 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800921 """
Jon Hallffb386d2014-11-21 13:43:38 -0800922 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -0400923 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400926 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700927 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 cmdStr += " -j"
930 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -0700931 if handle:
932 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -0800933 # TODO: Maybe make this less hardcoded
934 # ConsistentMap Exceptions
935 assert "org.onosproject.store.service" not in handle
936 # Node not leader
937 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -0700940 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -0700941 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -0800942 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800943 except TypeError:
944 main.log.exception( self.name + ": Object not as expected" )
945 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400946 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800947 main.log.error( self.name + ": EOF exception found" )
948 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400949 main.cleanup()
950 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800951 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800952 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400953 main.cleanup()
954 main.exit()
955
kelvin-onlabd3b64892015-01-20 13:26:24 -0800956 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -0800957 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400958 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -0800959
Jon Hallefbd9792015-03-05 16:11:36 -0800960 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 partial mac address
962
Jon Hall42db6dc2014-10-24 19:03:48 -0400963 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -0800964 """
Jon Hall42db6dc2014-10-24 19:03:48 -0400965 try:
kelvin8ec71442015-01-15 16:57:00 -0800966 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -0400967 return None
968 else:
969 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 rawHosts = self.hosts()
971 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -0800972 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -0800974 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -0800975 if not host:
976 pass
977 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -0400978 return host
979 return None
Jon Hallc6793552016-01-19 14:18:37 -0800980 except ( TypeError, ValueError ):
981 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800982 return None
Jon Hall42db6dc2014-10-24 19:03:48 -0400983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -0400986 main.cleanup()
987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800989 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -0400990 main.cleanup()
991 main.exit()
992
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -0800994 """
995 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -0400996 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -0800997
andrewonlab3f0a4af2014-10-17 12:25:14 -0400998 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001000 IMPORTANT:
1001 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001002 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001003 Furthermore, it assumes that value of VLAN is '-1'
1004 Description:
kelvin8ec71442015-01-15 16:57:00 -08001005 Converts mininet hosts ( h1, h2, h3... ) into
1006 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1007 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001008 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001010
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001012 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 hostHex = hex( int( host ) ).zfill( 12 )
1014 hostHex = str( hostHex ).replace( 'x', '0' )
1015 i = iter( str( hostHex ) )
1016 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1017 hostHex = hostHex + "/-1"
1018 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001019
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001021
Jon Halld4d4b372015-01-28 16:02:41 -08001022 except TypeError:
1023 main.log.exception( self.name + ": Object not as expected" )
1024 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001025 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001026 main.log.error( self.name + ": EOF exception found" )
1027 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001028 main.cleanup()
1029 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001031 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001032 main.cleanup()
1033 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001034
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 def addHostIntent( self, hostIdOne, hostIdTwo ):
kelvin8ec71442015-01-15 16:57:00 -08001036 """
andrewonlabe6745342014-10-17 14:29:13 -04001037 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 * hostIdOne: ONOS host id for host1
1039 * hostIdTwo: ONOS host id for host2
andrewonlabe6745342014-10-17 14:29:13 -04001040 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001041 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001042 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001043 Returns:
1044 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001045 """
andrewonlabe6745342014-10-17 14:29:13 -04001046 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 cmdStr = "add-host-intent " + str( hostIdOne ) +\
1048 " " + str( hostIdTwo )
1049 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001050 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001051 if re.search( "Error", handle ):
1052 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001053 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001054 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001055 else:
1056 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001057 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1058 match = re.search('id=0x([\da-f]+),', handle)
1059 if match:
1060 return match.group()[3:-1]
1061 else:
1062 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001063 main.log.debug( "Response from ONOS was: " +
1064 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001065 return None
Jon Hallc6793552016-01-19 14:18:37 -08001066 except AssertionError:
1067 main.log.exception( "" )
1068 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001069 except TypeError:
1070 main.log.exception( self.name + ": Object not as expected" )
1071 return None
andrewonlabe6745342014-10-17 14:29:13 -04001072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001073 main.log.error( self.name + ": EOF exception found" )
1074 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001075 main.cleanup()
1076 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001077 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001078 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001079 main.cleanup()
1080 main.exit()
1081
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001083 """
andrewonlab7b31d232014-10-24 13:31:47 -04001084 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 * ingressDevice: device id of ingress device
1086 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001087 Optional:
1088 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001089 Description:
1090 Adds an optical intent by specifying an ingress and egress device
1091 Returns:
1092 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001093 """
andrewonlab7b31d232014-10-24 13:31:47 -04001094 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1096 " " + str( egressDevice )
1097 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001098 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001099 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001100 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001101 main.log.error( "Error in adding Optical intent" )
1102 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001103 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001104 main.log.info( "Optical intent installed between " +
1105 str( ingressDevice ) + " and " +
1106 str( egressDevice ) )
1107 match = re.search('id=0x([\da-f]+),', handle)
1108 if match:
1109 return match.group()[3:-1]
1110 else:
1111 main.log.error( "Error, intent ID not found" )
1112 return None
Jon Hallc6793552016-01-19 14:18:37 -08001113 except AssertionError:
1114 main.log.exception( "" )
1115 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001116 except TypeError:
1117 main.log.exception( self.name + ": Object not as expected" )
1118 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001120 main.log.error( self.name + ": EOF exception found" )
1121 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001122 main.cleanup()
1123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001124 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001125 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001126 main.cleanup()
1127 main.exit()
1128
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001130 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 ingressDevice,
1132 egressDevice,
1133 portIngress="",
1134 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001135 ethType="",
1136 ethSrc="",
1137 ethDst="",
1138 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001140 ipProto="",
1141 ipSrc="",
1142 ipDst="",
1143 tcpSrc="",
1144 tcpDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001145 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001146 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001147 * ingressDevice: device id of ingress device
1148 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001149 Optional:
1150 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001151 * ethSrc: specify ethSrc ( i.e. src mac addr )
1152 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001153 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001155 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001156 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001157 * ipSrc: specify ip source address
1158 * ipDst: specify ip destination address
1159 * tcpSrc: specify tcp source port
1160 * tcpDst: specify tcp destination port
andrewonlab4dbb4d82014-10-17 18:22:31 -04001161 Description:
kelvin8ec71442015-01-15 16:57:00 -08001162 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001163 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 Returns:
1165 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001166
Jon Halle3f39ff2015-01-13 11:50:53 -08001167 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001168 options developers provide for point-to-point
1169 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001170 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001171 try:
kelvin8ec71442015-01-15 16:57:00 -08001172 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001173 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001175 and not ipProto and not ipSrc and not ipDst \
1176 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001177 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001178
andrewonlab289e4b72014-10-21 21:24:18 -04001179 else:
andrewonlab36af3822014-11-18 17:48:18 -05001180 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001181
andrewonlab0c0a6772014-10-22 12:31:18 -04001182 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001183 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001184 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001185 cmd += " --ethSrc " + str( ethSrc )
1186 if ethDst:
1187 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001188 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001189 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001190 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001191 cmd += " --lambda "
1192 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001193 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001194 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001195 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001196 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001197 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001198 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001199 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001200 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001201 cmd += " --tcpDst " + str( tcpDst )
andrewonlab289e4b72014-10-21 21:24:18 -04001202
kelvin8ec71442015-01-15 16:57:00 -08001203 # Check whether the user appended the port
1204 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 if "/" in ingressDevice:
1206 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001207 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001208 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001209 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001210 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001211 # Would it make sense to throw an exception and exit
1212 # the test?
1213 return None
andrewonlab36af3822014-11-18 17:48:18 -05001214
kelvin8ec71442015-01-15 16:57:00 -08001215 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 str( ingressDevice ) + "/" +\
1217 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001218
kelvin-onlabd3b64892015-01-20 13:26:24 -08001219 if "/" in egressDevice:
1220 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001221 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001222 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001223 main.log.error( "You must specify the egress port" )
1224 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001225
kelvin8ec71442015-01-15 16:57:00 -08001226 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001227 str( egressDevice ) + "/" +\
1228 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001229
kelvin-onlab898a6c62015-01-16 14:13:53 -08001230 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001231 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001233 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001234 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001236 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001237 # TODO: print out all the options in this message?
1238 main.log.info( "Point-to-point intent installed between " +
1239 str( ingressDevice ) + " and " +
1240 str( egressDevice ) )
1241 match = re.search('id=0x([\da-f]+),', handle)
1242 if match:
1243 return match.group()[3:-1]
1244 else:
1245 main.log.error( "Error, intent ID not found" )
1246 return None
Jon Hallc6793552016-01-19 14:18:37 -08001247 except AssertionError:
1248 main.log.exception( "" )
1249 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001250 except TypeError:
1251 main.log.exception( self.name + ": Object not as expected" )
1252 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001256 main.cleanup()
1257 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001258 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001259 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001260 main.cleanup()
1261 main.exit()
1262
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 self,
shahshreyac2f97072015-03-19 17:04:29 -07001265 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001267 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 ethType="",
1270 ethSrc="",
1271 ethDst="",
1272 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001273 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001274 ipProto="",
1275 ipSrc="",
1276 ipDst="",
1277 tcpSrc="",
1278 tcpDst="",
1279 setEthSrc="",
1280 setEthDst="" ):
kelvin8ec71442015-01-15 16:57:00 -08001281 """
shahshreyad0c80432014-12-04 16:56:05 -08001282 Note:
shahshreya70622b12015-03-19 17:19:00 -07001283 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001284 is same. That is, all ingress devices include port numbers
1285 with a "/" or all ingress devices could specify device
1286 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001287 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001288 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001289 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001290 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001291 Optional:
1292 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001293 * ethSrc: specify ethSrc ( i.e. src mac addr )
1294 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001295 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001296 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001297 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001298 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001299 * ipSrc: specify ip source address
1300 * ipDst: specify ip destination address
1301 * tcpSrc: specify tcp source port
1302 * tcpDst: specify tcp destination port
1303 * setEthSrc: action to Rewrite Source MAC Address
1304 * setEthDst: action to Rewrite Destination MAC Address
1305 Description:
kelvin8ec71442015-01-15 16:57:00 -08001306 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001307 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001308 Returns:
1309 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001310
Jon Halle3f39ff2015-01-13 11:50:53 -08001311 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001312 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001313 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001314 """
shahshreyad0c80432014-12-04 16:56:05 -08001315 try:
kelvin8ec71442015-01-15 16:57:00 -08001316 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001317 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001319 and not ipProto and not ipSrc and not ipDst\
1320 and not tcpSrc and not tcpDst and not setEthSrc\
1321 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001322 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001323
1324 else:
1325 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001326
shahshreyad0c80432014-12-04 16:56:05 -08001327 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001328 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001329 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001330 cmd += " --ethSrc " + str( ethSrc )
1331 if ethDst:
1332 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001333 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001334 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001336 cmd += " --lambda "
1337 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001338 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001339 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001341 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001342 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001343 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001344 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001345 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001346 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001347 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001348 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001349 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " --setEthDst " + str( setEthDst )
shahshreyad0c80432014-12-04 16:56:05 -08001351
kelvin8ec71442015-01-15 16:57:00 -08001352 # Check whether the user appended the port
1353 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001354
1355 if portIngressList is None:
1356 for ingressDevice in ingressDeviceList:
1357 if "/" in ingressDevice:
1358 cmd += " " + str( ingressDevice )
1359 else:
1360 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001361 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001362 # TODO: perhaps more meaningful return
1363 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001364 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001365 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001366 for ingressDevice, portIngress in zip( ingressDeviceList,
1367 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001368 cmd += " " + \
1369 str( ingressDevice ) + "/" +\
1370 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001371 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001372 main.log.error( "Device list and port list does not " +
1373 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001374 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 if "/" in egressDevice:
1376 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001377 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001379 main.log.error( "You must specify " +
1380 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001381 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001382
kelvin8ec71442015-01-15 16:57:00 -08001383 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001384 str( egressDevice ) + "/" +\
1385 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001386 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001387 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001388 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001390 main.log.error( "Error in adding multipoint-to-singlepoint " +
1391 "intent" )
1392 return None
shahshreyad0c80432014-12-04 16:56:05 -08001393 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001394 match = re.search('id=0x([\da-f]+),', handle)
1395 if match:
1396 return match.group()[3:-1]
1397 else:
1398 main.log.error( "Error, intent ID not found" )
1399 return None
Jon Hallc6793552016-01-19 14:18:37 -08001400 except AssertionError:
1401 main.log.exception( "" )
1402 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001403 except TypeError:
1404 main.log.exception( self.name + ": Object not as expected" )
1405 return None
1406 except pexpect.EOF:
1407 main.log.error( self.name + ": EOF exception found" )
1408 main.log.error( self.name + ": " + self.handle.before )
1409 main.cleanup()
1410 main.exit()
1411 except Exception:
1412 main.log.exception( self.name + ": Uncaught exception!" )
1413 main.cleanup()
1414 main.exit()
1415
1416 def addSinglepointToMultipointIntent(
1417 self,
1418 ingressDevice,
1419 egressDeviceList,
1420 portIngress="",
1421 portEgressList=None,
1422 ethType="",
1423 ethSrc="",
1424 ethDst="",
1425 bandwidth="",
1426 lambdaAlloc=False,
1427 ipProto="",
1428 ipSrc="",
1429 ipDst="",
1430 tcpSrc="",
1431 tcpDst="",
1432 setEthSrc="",
1433 setEthDst="" ):
1434 """
1435 Note:
1436 This function assumes the format of all egress devices
1437 is same. That is, all egress devices include port numbers
1438 with a "/" or all egress devices could specify device
1439 ids and port numbers seperately.
1440 Required:
1441 * EgressDeviceList: List of device ids of egress device
1442 ( Atleast 2 eress devices required in the list )
1443 * ingressDevice: device id of ingress device
1444 Optional:
1445 * ethType: specify ethType
1446 * ethSrc: specify ethSrc ( i.e. src mac addr )
1447 * ethDst: specify ethDst ( i.e. dst mac addr )
1448 * bandwidth: specify bandwidth capacity of link
1449 * lambdaAlloc: if True, intent will allocate lambda
1450 for the specified intent
1451 * ipProto: specify ip protocol
1452 * ipSrc: specify ip source address
1453 * ipDst: specify ip destination address
1454 * tcpSrc: specify tcp source port
1455 * tcpDst: specify tcp destination port
1456 * setEthSrc: action to Rewrite Source MAC Address
1457 * setEthDst: action to Rewrite Destination MAC Address
1458 Description:
1459 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1460 specifying device id's and optional fields
1461 Returns:
1462 A string of the intent id or None on error
1463
1464 NOTE: This function may change depending on the
1465 options developers provide for singlepoint-to-multipoint
1466 intent via cli
1467 """
1468 try:
1469 # If there are no optional arguments
1470 if not ethType and not ethSrc and not ethDst\
1471 and not bandwidth and not lambdaAlloc\
1472 and not ipProto and not ipSrc and not ipDst\
1473 and not tcpSrc and not tcpDst and not setEthSrc\
1474 and not setEthDst:
1475 cmd = "add-single-to-multi-intent"
1476
1477 else:
1478 cmd = "add-single-to-multi-intent"
1479
1480 if ethType:
1481 cmd += " --ethType " + str( ethType )
1482 if ethSrc:
1483 cmd += " --ethSrc " + str( ethSrc )
1484 if ethDst:
1485 cmd += " --ethDst " + str( ethDst )
1486 if bandwidth:
1487 cmd += " --bandwidth " + str( bandwidth )
1488 if lambdaAlloc:
1489 cmd += " --lambda "
1490 if ipProto:
1491 cmd += " --ipProto " + str( ipProto )
1492 if ipSrc:
1493 cmd += " --ipSrc " + str( ipSrc )
1494 if ipDst:
1495 cmd += " --ipDst " + str( ipDst )
1496 if tcpSrc:
1497 cmd += " --tcpSrc " + str( tcpSrc )
1498 if tcpDst:
1499 cmd += " --tcpDst " + str( tcpDst )
1500 if setEthSrc:
1501 cmd += " --setEthSrc " + str( setEthSrc )
1502 if setEthDst:
1503 cmd += " --setEthDst " + str( setEthDst )
1504
1505 # Check whether the user appended the port
1506 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001507
kelvin-onlabb9408212015-04-01 13:34:04 -07001508 if "/" in ingressDevice:
1509 cmd += " " + str( ingressDevice )
1510 else:
1511 if not portIngress:
1512 main.log.error( "You must specify " +
1513 "the Ingress port" )
1514 return main.FALSE
1515
1516 cmd += " " +\
1517 str( ingressDevice ) + "/" +\
1518 str( portIngress )
1519
1520 if portEgressList is None:
1521 for egressDevice in egressDeviceList:
1522 if "/" in egressDevice:
1523 cmd += " " + str( egressDevice )
1524 else:
1525 main.log.error( "You must specify " +
1526 "the egress port" )
1527 # TODO: perhaps more meaningful return
1528 return main.FALSE
1529 else:
1530 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001531 for egressDevice, portEgress in zip( egressDeviceList,
1532 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001533 cmd += " " + \
1534 str( egressDevice ) + "/" +\
1535 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001536 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001537 main.log.error( "Device list and port list does not " +
1538 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001539 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001540 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001541 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001542 # If error, return error message
1543 if re.search( "Error", handle ):
1544 main.log.error( "Error in adding singlepoint-to-multipoint " +
1545 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001546 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001547 else:
1548 match = re.search('id=0x([\da-f]+),', handle)
1549 if match:
1550 return match.group()[3:-1]
1551 else:
1552 main.log.error( "Error, intent ID not found" )
1553 return None
Jon Hallc6793552016-01-19 14:18:37 -08001554 except AssertionError:
1555 main.log.exception( "" )
1556 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001557 except TypeError:
1558 main.log.exception( self.name + ": Object not as expected" )
1559 return None
shahshreyad0c80432014-12-04 16:56:05 -08001560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001561 main.log.error( self.name + ": EOF exception found" )
1562 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001563 main.cleanup()
1564 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001565 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001566 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001567 main.cleanup()
1568 main.exit()
1569
Hari Krishna9e232602015-04-13 17:29:08 -07001570 def addMplsIntent(
1571 self,
1572 ingressDevice,
1573 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001574 ingressPort="",
1575 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001576 ethType="",
1577 ethSrc="",
1578 ethDst="",
1579 bandwidth="",
1580 lambdaAlloc=False,
1581 ipProto="",
1582 ipSrc="",
1583 ipDst="",
1584 tcpSrc="",
1585 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001586 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001587 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001588 priority=""):
1589 """
1590 Required:
1591 * ingressDevice: device id of ingress device
1592 * egressDevice: device id of egress device
1593 Optional:
1594 * ethType: specify ethType
1595 * ethSrc: specify ethSrc ( i.e. src mac addr )
1596 * ethDst: specify ethDst ( i.e. dst mac addr )
1597 * bandwidth: specify bandwidth capacity of link
1598 * lambdaAlloc: if True, intent will allocate lambda
1599 for the specified intent
1600 * ipProto: specify ip protocol
1601 * ipSrc: specify ip source address
1602 * ipDst: specify ip destination address
1603 * tcpSrc: specify tcp source port
1604 * tcpDst: specify tcp destination port
1605 * ingressLabel: Ingress MPLS label
1606 * egressLabel: Egress MPLS label
1607 Description:
1608 Adds MPLS intent by
1609 specifying device id's and optional fields
1610 Returns:
1611 A string of the intent id or None on error
1612
1613 NOTE: This function may change depending on the
1614 options developers provide for MPLS
1615 intent via cli
1616 """
1617 try:
1618 # If there are no optional arguments
1619 if not ethType and not ethSrc and not ethDst\
1620 and not bandwidth and not lambdaAlloc \
1621 and not ipProto and not ipSrc and not ipDst \
1622 and not tcpSrc and not tcpDst and not ingressLabel \
1623 and not egressLabel:
1624 cmd = "add-mpls-intent"
1625
1626 else:
1627 cmd = "add-mpls-intent"
1628
1629 if ethType:
1630 cmd += " --ethType " + str( ethType )
1631 if ethSrc:
1632 cmd += " --ethSrc " + str( ethSrc )
1633 if ethDst:
1634 cmd += " --ethDst " + str( ethDst )
1635 if bandwidth:
1636 cmd += " --bandwidth " + str( bandwidth )
1637 if lambdaAlloc:
1638 cmd += " --lambda "
1639 if ipProto:
1640 cmd += " --ipProto " + str( ipProto )
1641 if ipSrc:
1642 cmd += " --ipSrc " + str( ipSrc )
1643 if ipDst:
1644 cmd += " --ipDst " + str( ipDst )
1645 if tcpSrc:
1646 cmd += " --tcpSrc " + str( tcpSrc )
1647 if tcpDst:
1648 cmd += " --tcpDst " + str( tcpDst )
1649 if ingressLabel:
1650 cmd += " --ingressLabel " + str( ingressLabel )
1651 if egressLabel:
1652 cmd += " --egressLabel " + str( egressLabel )
1653 if priority:
1654 cmd += " --priority " + str( priority )
1655
1656 # Check whether the user appended the port
1657 # or provided it as an input
1658 if "/" in ingressDevice:
1659 cmd += " " + str( ingressDevice )
1660 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001661 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001662 main.log.error( "You must specify the ingress port" )
1663 return None
1664
1665 cmd += " " + \
1666 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001667 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001668
1669 if "/" in egressDevice:
1670 cmd += " " + str( egressDevice )
1671 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001672 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001673 main.log.error( "You must specify the egress port" )
1674 return None
1675
1676 cmd += " " +\
1677 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001678 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001679
1680 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001681 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001682 # If error, return error message
1683 if re.search( "Error", handle ):
1684 main.log.error( "Error in adding mpls intent" )
1685 return None
1686 else:
1687 # TODO: print out all the options in this message?
1688 main.log.info( "MPLS intent installed between " +
1689 str( ingressDevice ) + " and " +
1690 str( egressDevice ) )
1691 match = re.search('id=0x([\da-f]+),', handle)
1692 if match:
1693 return match.group()[3:-1]
1694 else:
1695 main.log.error( "Error, intent ID not found" )
1696 return None
Jon Hallc6793552016-01-19 14:18:37 -08001697 except AssertionError:
1698 main.log.exception( "" )
1699 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001700 except TypeError:
1701 main.log.exception( self.name + ": Object not as expected" )
1702 return None
1703 except pexpect.EOF:
1704 main.log.error( self.name + ": EOF exception found" )
1705 main.log.error( self.name + ": " + self.handle.before )
1706 main.cleanup()
1707 main.exit()
1708 except Exception:
1709 main.log.exception( self.name + ": Uncaught exception!" )
1710 main.cleanup()
1711 main.exit()
1712
Jon Hallefbd9792015-03-05 16:11:36 -08001713 def removeIntent( self, intentId, app='org.onosproject.cli',
1714 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001715 """
shahshreya1c818fc2015-02-26 13:44:08 -08001716 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001717 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001718 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001719 -p or --purge: Purge the intent from the store after removal
1720
Jon Halle3f39ff2015-01-13 11:50:53 -08001721 Returns:
1722 main.False on error and
1723 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001724 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001725 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001726 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001727 if purge:
1728 cmdStr += " -p"
1729 if sync:
1730 cmdStr += " -s"
1731
1732 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001734 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001735 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001736 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001737 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001738 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001739 # TODO: Should this be main.TRUE
1740 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001741 except AssertionError:
1742 main.log.exception( "" )
1743 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001744 except TypeError:
1745 main.log.exception( self.name + ": Object not as expected" )
1746 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001748 main.log.error( self.name + ": EOF exception found" )
1749 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001750 main.cleanup()
1751 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001752 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001753 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001754 main.cleanup()
1755 main.exit()
1756
Jeremy42df2e72016-02-23 16:37:46 -08001757 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1758 """
1759 Description:
1760 Remove all the intents
1761 Optional args:-
1762 -s or --sync: Waits for the removal before returning
1763 -p or --purge: Purge the intent from the store after removal
1764 Returns:
1765 Returns main.TRUE if all intents are removed, otherwise returns
1766 main.FALSE; Returns None for exception
1767 """
1768 try:
1769 cmdStr = "remove-intent"
1770 if purge:
1771 cmdStr += " -p"
1772 if sync:
1773 cmdStr += " -s"
1774
1775 cmdStr += " " + app
1776 handle = self.sendline( cmdStr )
1777 assert "Command not found:" not in handle, handle
1778 if re.search( "Error", handle ):
1779 main.log.error( "Error in removing intent" )
1780 return main.FALSE
1781 else:
1782 return main.TRUE
1783 except AssertionError:
1784 main.log.exception( "" )
1785 return None
1786 except TypeError:
1787 main.log.exception( self.name + ": Object not as expected" )
1788 return None
1789 except pexpect.EOF:
1790 main.log.error( self.name + ": EOF exception found" )
1791 main.log.error( self.name + ": " + self.handle.before )
1792 main.cleanup()
1793 main.exit()
1794 except Exception:
1795 main.log.exception( self.name + ": Uncaught exception!" )
1796 main.cleanup()
1797 main.exit()
1798
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001799 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001800 """
1801 Purges all WITHDRAWN Intents
1802 """
1803 try:
1804 cmdStr = "purge-intents"
1805 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001806 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001807 if re.search( "Error", handle ):
1808 main.log.error( "Error in purging intents" )
1809 return main.FALSE
1810 else:
1811 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001812 except AssertionError:
1813 main.log.exception( "" )
1814 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001815 except TypeError:
1816 main.log.exception( self.name + ": Object not as expected" )
1817 return None
1818 except pexpect.EOF:
1819 main.log.error( self.name + ": EOF exception found" )
1820 main.log.error( self.name + ": " + self.handle.before )
1821 main.cleanup()
1822 main.exit()
1823 except Exception:
1824 main.log.exception( self.name + ": Uncaught exception!" )
1825 main.cleanup()
1826 main.exit()
1827
kelvin-onlabd3b64892015-01-20 13:26:24 -08001828 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001829 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001830 NOTE: This method should be used after installing application:
1831 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001832 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001833 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001834 Description:
1835 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001836 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001837 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001838 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001839 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001840 cmdStr += " -j"
1841 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001842 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001843 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001844 except AssertionError:
1845 main.log.exception( "" )
1846 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001847 except TypeError:
1848 main.log.exception( self.name + ": Object not as expected" )
1849 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001850 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001851 main.log.error( self.name + ": EOF exception found" )
1852 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001853 main.cleanup()
1854 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001855 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001856 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001857 main.cleanup()
1858 main.exit()
1859
pingping-lin54b03372015-08-13 14:43:10 -07001860 def ipv4RouteNumber( self ):
1861 """
1862 NOTE: This method should be used after installing application:
1863 onos-app-sdnip
1864 Description:
1865 Obtain the total IPv4 routes number in the system
1866 """
1867 try:
1868 cmdStr = "routes -s -j"
1869 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001870 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001871 jsonResult = json.loads( handle )
1872 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001873 except AssertionError:
1874 main.log.exception( "" )
1875 return None
1876 except ( TypeError, ValueError ):
1877 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001878 return None
1879 except pexpect.EOF:
1880 main.log.error( self.name + ": EOF exception found" )
1881 main.log.error( self.name + ": " + self.handle.before )
1882 main.cleanup()
1883 main.exit()
1884 except Exception:
1885 main.log.exception( self.name + ": Uncaught exception!" )
1886 main.cleanup()
1887 main.exit()
1888
pingping-lin8244a3b2015-09-16 13:36:56 -07001889 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08001890 """
andrewonlabe6745342014-10-17 14:29:13 -04001891 Description:
Jon Hallff566d52016-01-15 14:45:36 -08001892 Obtain intents from the ONOS cli.
1893 Optional:
1894 * jsonFormat: Enable output formatting in json, default to True
1895 * summary: Whether only output the intent summary, defaults to False
1896 * type: Only output a certain type of intent. This options is valid
1897 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08001898 """
andrewonlabe6745342014-10-17 14:29:13 -04001899 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001900 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07001901 if summary:
1902 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001903 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001904 cmdStr += " -j"
1905 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001906 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07001907 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07001908 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08001909 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07001910 else:
Jon Hallff566d52016-01-15 14:45:36 -08001911 intentType = ""
1912 # IF we want the summary of a specific intent type
1913 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07001914 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08001915 if intentType in jsonResult.keys():
1916 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07001917 else:
Jon Hallff566d52016-01-15 14:45:36 -08001918 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07001919 return handle
1920 else:
1921 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001922 except AssertionError:
1923 main.log.exception( "" )
1924 return None
1925 except ( TypeError, ValueError ):
1926 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07001927 return None
1928 except pexpect.EOF:
1929 main.log.error( self.name + ": EOF exception found" )
1930 main.log.error( self.name + ": " + self.handle.before )
1931 main.cleanup()
1932 main.exit()
1933 except Exception:
1934 main.log.exception( self.name + ": Uncaught exception!" )
1935 main.cleanup()
1936 main.exit()
1937
kelvin-onlab54400a92015-02-26 18:05:51 -08001938 def getIntentState(self, intentsId, intentsJson=None):
1939 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001940 Check intent state.
1941 Accepts a single intent ID (string type) or a list of intent IDs.
1942 Returns the state(string type) of the id if a single intent ID is
1943 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08001944 Returns a dictionary with intent IDs as the key and its
1945 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08001946 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08001947 intentId: intent ID (string type)
1948 intentsJson: parsed json object from the onos:intents api
1949 Returns:
1950 state = An intent's state- INSTALL,WITHDRAWN etc.
1951 stateDict = Dictionary of intent's state. intent ID as the keys and
1952 state as the values.
1953 """
kelvin-onlab54400a92015-02-26 18:05:51 -08001954 try:
1955 state = "State is Undefined"
1956 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08001957 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08001958 else:
Jon Hallc6793552016-01-19 14:18:37 -08001959 rawJson = intentsJson
1960 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08001961 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08001962 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001963 if intentsId == intent[ 'id' ]:
1964 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08001965 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001966 main.log.info( "Cannot find intent ID" + str( intentsId ) +
1967 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001968 return state
Jon Hallefbd9792015-03-05 16:11:36 -08001969 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001970 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001971 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08001972 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08001973 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001974 if intentsId[ i ] == intents[ 'id' ]:
1975 stateDict[ 'state' ] = intents[ 'state' ]
1976 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08001977 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08001978 break
Jon Hallefbd9792015-03-05 16:11:36 -08001979 if len( intentsId ) != len( dictList ):
1980 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08001981 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08001982 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001983 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08001984 return None
Jon Hallc6793552016-01-19 14:18:37 -08001985 except ( TypeError, ValueError ):
1986 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08001987 return None
1988 except pexpect.EOF:
1989 main.log.error( self.name + ": EOF exception found" )
1990 main.log.error( self.name + ": " + self.handle.before )
1991 main.cleanup()
1992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001993 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08001994 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001995 main.cleanup()
1996 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07001997
kelvin-onlabf512e942015-06-08 19:42:59 -07001998 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07001999 """
2000 Description:
2001 Check intents state
2002 Required:
2003 intentsId - List of intents ID to be checked
2004 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002005 expectedState - Check the expected state(s) of each intents
2006 state in the list.
2007 *NOTE: You can pass in a list of expected state,
2008 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002009 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002010 Returns main.TRUE only if all intent are the same as expected states
2011 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002012 """
2013 try:
2014 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002015 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002016 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002017 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002018 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002019 "getting intents state" )
2020 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002021
2022 if isinstance( expectedState, types.StringType ):
2023 for intents in intentsDict:
2024 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002025 main.log.debug( self.name + " : Intent ID - " +
2026 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002027 " actual state = " +
2028 intents.get( 'state' )
2029 + " does not equal expected state = "
2030 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002031 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002032
2033 elif isinstance( expectedState, types.ListType ):
2034 for intents in intentsDict:
2035 if not any( state == intents.get( 'state' ) for state in
2036 expectedState ):
2037 main.log.debug( self.name + " : Intent ID - " +
2038 intents.get( 'id' ) +
2039 " actual state = " +
2040 intents.get( 'state' ) +
2041 " does not equal expected states = "
2042 + str( expectedState ) )
2043 returnValue = main.FALSE
2044
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002045 if returnValue == main.TRUE:
2046 main.log.info( self.name + ": All " +
2047 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002048 " intents are in " + str( expectedState ) +
2049 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002050 return returnValue
2051 except TypeError:
2052 main.log.exception( self.name + ": Object not as expected" )
2053 return None
2054 except pexpect.EOF:
2055 main.log.error( self.name + ": EOF exception found" )
2056 main.log.error( self.name + ": " + self.handle.before )
2057 main.cleanup()
2058 main.exit()
2059 except Exception:
2060 main.log.exception( self.name + ": Uncaught exception!" )
2061 main.cleanup()
2062 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002063
GlennRCed771242016-01-13 17:02:47 -08002064 def checkIntentSummary( self, timeout=60 ):
2065 """
2066 Description:
2067 Check the number of installed intents.
2068 Optional:
2069 timeout - the timeout for pexcept
2070 Return:
2071 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2072 , otherwise, returns main.FALSE.
2073 """
2074
2075 try:
2076 cmd = "intents -s -j"
2077
2078 # Check response if something wrong
2079 response = self.sendline( cmd, timeout=timeout )
2080 if response == None:
2081 return main.False
2082 response = json.loads( response )
2083
2084 # get total and installed number, see if they are match
2085 allState = response.get( 'all' )
2086 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002087 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002088 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002089 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002090 return main.FALSE
2091
Jon Hallc6793552016-01-19 14:18:37 -08002092 except ( TypeError, ValueError ):
2093 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002094 return None
2095 except pexpect.EOF:
2096 main.log.error( self.name + ": EOF exception found" )
2097 main.log.error( self.name + ": " + self.handle.before )
2098 main.cleanup()
2099 main.exit()
2100 except Exception:
2101 main.log.exception( self.name + ": Uncaught exception!" )
2102 main.cleanup()
2103 main.exit()
2104
2105 def flows( self, state="", jsonFormat=True, timeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -08002106 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002107 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002108 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002109 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002110 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002111 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002112 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002113 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002114 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002115 cmdStr += " -j "
2116 cmdStr += state
Jon Hallc6793552016-01-19 14:18:37 -08002117 handle = self.sendline( cmdStr, timeout=timeout )
2118 assert "Command not found:" not in handle, handle
2119 if re.search( "Error:", handle ):
2120 main.log.error( self.name + ": flows() response: " +
2121 str( handle ) )
2122 return handle
2123 except AssertionError:
2124 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002125 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002126 except TypeError:
2127 main.log.exception( self.name + ": Object not as expected" )
2128 return None
Jon Hallc6793552016-01-19 14:18:37 -08002129 except pexpect.TIMEOUT:
2130 main.log.error( self.name + ": ONOS timeout" )
2131 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002135 main.cleanup()
2136 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002137 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002138 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002139 main.cleanup()
2140 main.exit()
2141
GlennRCed771242016-01-13 17:02:47 -08002142
Jon Hallc6793552016-01-19 14:18:37 -08002143 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002144 """
2145 Description:
GlennRCed771242016-01-13 17:02:47 -08002146 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002147 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2148 if the count of those states is 0, which means all current flows
2149 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002150 Optional:
GlennRCed771242016-01-13 17:02:47 -08002151 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002152 Return:
2153 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002154 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002155 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002156 """
2157 try:
GlennRCed771242016-01-13 17:02:47 -08002158 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2159 checkedStates = []
2160 statesCount = [0, 0, 0, 0]
2161 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002162 rawFlows = self.flows( state=s, timeout = timeout )
2163 checkedStates.append( json.loads( rawFlows ) )
2164 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002165 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002166 try:
2167 statesCount[i] += int( c.get( "flowCount" ) )
2168 except TypeError:
2169 main.log.exception( "Json object not as expected" )
2170 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002171
GlennRCed771242016-01-13 17:02:47 -08002172 # We want to count PENDING_ADD if isPENDING is true
2173 if isPENDING:
2174 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2175 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002176 else:
GlennRCed771242016-01-13 17:02:47 -08002177 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2178 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002179 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002180 except ( TypeError, ValueError ):
2181 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002182 return None
2183 except pexpect.EOF:
2184 main.log.error( self.name + ": EOF exception found" )
2185 main.log.error( self.name + ": " + self.handle.before )
2186 main.cleanup()
2187 main.exit()
2188 except Exception:
2189 main.log.exception( self.name + ": Uncaught exception!" )
2190 main.cleanup()
2191 main.exit()
2192
GlennRCed771242016-01-13 17:02:47 -08002193 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2194 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002195 """
andrewonlab87852b02014-11-19 18:44:19 -05002196 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002197 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002198 a specific point-to-point intent definition
2199 Required:
GlennRCed771242016-01-13 17:02:47 -08002200 * ingress: specify source dpid
2201 * egress: specify destination dpid
2202 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002203 Optional:
GlennRCed771242016-01-13 17:02:47 -08002204 * offset: the keyOffset is where the next batch of intents
2205 will be installed
2206 Returns: If failed to push test intents, it will returen None,
2207 if successful, return true.
2208 Timeout expection will return None,
2209 TypeError will return false
2210 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002211 """
andrewonlab87852b02014-11-19 18:44:19 -05002212 try:
GlennRCed771242016-01-13 17:02:47 -08002213 if background:
2214 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002215 else:
GlennRCed771242016-01-13 17:02:47 -08002216 back = ""
2217 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002218 ingress,
2219 egress,
2220 batchSize,
2221 offset,
2222 back )
GlennRCed771242016-01-13 17:02:47 -08002223 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002224 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002225 main.log.info( response )
2226 if response == None:
2227 return None
2228
2229 # TODO: We should handle if there is failure in installation
2230 return main.TRUE
2231
Jon Hallc6793552016-01-19 14:18:37 -08002232 except AssertionError:
2233 main.log.exception( "" )
2234 return None
GlennRCed771242016-01-13 17:02:47 -08002235 except pexpect.TIMEOUT:
2236 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002237 return None
andrewonlab87852b02014-11-19 18:44:19 -05002238 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002239 main.log.error( self.name + ": EOF exception found" )
2240 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002241 main.cleanup()
2242 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002243 except TypeError:
2244 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002245 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002246 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002247 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002248 main.cleanup()
2249 main.exit()
2250
YPZhangf6f14a02016-01-28 15:17:31 -08002251 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002252 """
2253 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002254 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002255 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002256 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002257 """
YPZhange3109a72016-02-02 11:25:37 -08002258
YPZhangb5d3f832016-01-23 22:54:26 -08002259 try:
YPZhange3109a72016-02-02 11:25:37 -08002260 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002261 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002262 totalFlows = self.sendline( cmd, timeout=timeout )
2263
2264 if totalFlows == None:
2265 # if timeout, we will get total number of all flows, and subtract other states
2266 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2267 checkedStates = []
2268 totalFlows = 0
2269 statesCount = [0, 0, 0, 0]
2270
2271 # get total flows from summary
2272 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2273 totalFlows = int( response.get("flows") )
2274
2275 for s in states:
2276 rawFlows = self.flows( state=s, timeout = timeout )
2277 if rawFlows == None:
2278 # if timeout, return the total flows number from summary command
2279 return totalFlows
2280 checkedStates.append( json.loads( rawFlows ) )
2281
2282 # Calculate ADDED flows number, equal total subtracts others
2283 for i in range( len( states ) ):
2284 for c in checkedStates[i]:
2285 try:
2286 statesCount[i] += int( c.get( "flowCount" ) )
2287 except TypeError:
2288 main.log.exception( "Json object not as expected" )
2289 totalFlows = totalFlows - int( statesCount[i] )
2290 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2291
2292 return totalFlows
2293
2294 return totalFlows
2295
YPZhangb5d3f832016-01-23 22:54:26 -08002296 except TypeError:
2297 main.log.exception( self.name + ": Object not as expected" )
2298 return None
2299 except pexpect.EOF:
2300 main.log.error( self.name + ": EOF exception found" )
2301 main.log.error( self.name + ": " + self.handle.before )
2302 main.cleanup()
2303 main.exit()
2304 except Exception:
2305 main.log.exception( self.name + ": Uncaught exception!" )
2306 main.cleanup()
2307 main.exit()
2308
2309 def getTotalIntentsNum( self ):
2310 """
2311 Description:
2312 Get the total number of intents, include every states.
2313 Return:
2314 The number of intents
2315 """
2316 try:
2317 cmd = "summary -j"
2318 response = self.sendline( cmd )
2319 if response == None:
2320 return -1
2321 response = json.loads( response )
2322 return int( response.get("intents") )
2323 except TypeError:
2324 main.log.exception( self.name + ": Object not as expected" )
2325 return None
2326 except pexpect.EOF:
2327 main.log.error( self.name + ": EOF exception found" )
2328 main.log.error( self.name + ": " + self.handle.before )
2329 main.cleanup()
2330 main.exit()
2331 except Exception:
2332 main.log.exception( self.name + ": Uncaught exception!" )
2333 main.cleanup()
2334 main.exit()
2335
kelvin-onlabd3b64892015-01-20 13:26:24 -08002336 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002337 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002338 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002339 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002340 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002341 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002342 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002343 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002345 cmdStr += " -j"
2346 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002347 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002348 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002349 except AssertionError:
2350 main.log.exception( "" )
2351 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002352 except TypeError:
2353 main.log.exception( self.name + ": Object not as expected" )
2354 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002355 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002356 main.log.error( self.name + ": EOF exception found" )
2357 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002358 main.cleanup()
2359 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002360 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002361 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002362 main.cleanup()
2363 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002364
kelvin-onlabd3b64892015-01-20 13:26:24 -08002365 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002366 """
2367 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002368 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002369 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002370 """
andrewonlab867212a2014-10-22 20:13:38 -04002371 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002372 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002373 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002374 cmdStr += " -j"
2375 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002376 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002377 if handle:
2378 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002379 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002380 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002381 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002382 else:
2383 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002384 except AssertionError:
2385 main.log.exception( "" )
2386 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002387 except TypeError:
2388 main.log.exception( self.name + ": Object not as expected" )
2389 return None
andrewonlab867212a2014-10-22 20:13:38 -04002390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002391 main.log.error( self.name + ": EOF exception found" )
2392 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002393 main.cleanup()
2394 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002395 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002396 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002397 main.cleanup()
2398 main.exit()
2399
kelvin8ec71442015-01-15 16:57:00 -08002400 # Wrapper functions ****************
2401 # Wrapper functions use existing driver
2402 # functions and extends their use case.
2403 # For example, we may use the output of
2404 # a normal driver function, and parse it
2405 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002406
kelvin-onlabd3b64892015-01-20 13:26:24 -08002407 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002408 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002409 Description:
2410 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002411 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002412 try:
kelvin8ec71442015-01-15 16:57:00 -08002413 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002414 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002415 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002416
kelvin8ec71442015-01-15 16:57:00 -08002417 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002418 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2419 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002420 match = re.search('id=0x([\da-f]+),', intents)
2421 if match:
2422 tmpId = match.group()[3:-1]
2423 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002424 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002425
Jon Halld4d4b372015-01-28 16:02:41 -08002426 except TypeError:
2427 main.log.exception( self.name + ": Object not as expected" )
2428 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002429 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002430 main.log.error( self.name + ": EOF exception found" )
2431 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002432 main.cleanup()
2433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002434 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002435 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002436 main.cleanup()
2437 main.exit()
2438
Jon Hall30b82fa2015-03-04 17:15:43 -08002439 def FlowAddedCount( self, deviceId ):
2440 """
2441 Determine the number of flow rules for the given device id that are
2442 in the added state
2443 """
2444 try:
2445 cmdStr = "flows any " + str( deviceId ) + " | " +\
2446 "grep 'state=ADDED' | wc -l"
2447 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002448 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002449 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002450 except AssertionError:
2451 main.log.exception( "" )
2452 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002453 except pexpect.EOF:
2454 main.log.error( self.name + ": EOF exception found" )
2455 main.log.error( self.name + ": " + self.handle.before )
2456 main.cleanup()
2457 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002458 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002459 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002460 main.cleanup()
2461 main.exit()
2462
kelvin-onlabd3b64892015-01-20 13:26:24 -08002463 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002464 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002465 Use 'devices' function to obtain list of all devices
2466 and parse the result to obtain a list of all device
2467 id's. Returns this list. Returns empty list if no
2468 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002469 List is ordered sequentially
2470
andrewonlab3e15ead2014-10-15 14:21:34 -04002471 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002472 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002473 the ids. By obtaining the list of device ids on the fly,
2474 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002475 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002476 try:
kelvin8ec71442015-01-15 16:57:00 -08002477 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002478 devicesStr = self.devices( jsonFormat=False )
2479 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002480
kelvin-onlabd3b64892015-01-20 13:26:24 -08002481 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002482 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002483 return idList
kelvin8ec71442015-01-15 16:57:00 -08002484
2485 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002486 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002487 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002488 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002489 # Split list further into arguments before and after string
2490 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002491 # append to idList
2492 for arg in tempList:
2493 idList.append( arg.split( "id=" )[ 1 ] )
2494 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002495
Jon Halld4d4b372015-01-28 16:02:41 -08002496 except TypeError:
2497 main.log.exception( self.name + ": Object not as expected" )
2498 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002502 main.cleanup()
2503 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002504 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002505 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002506 main.cleanup()
2507 main.exit()
2508
kelvin-onlabd3b64892015-01-20 13:26:24 -08002509 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002510 """
andrewonlab7c211572014-10-15 16:45:20 -04002511 Uses 'nodes' function to obtain list of all nodes
2512 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002513 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002514 Returns:
2515 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002516 """
andrewonlab7c211572014-10-15 16:45:20 -04002517 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002518 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002519 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002520 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002521 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002522 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002523 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002524 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002525 nodesJson = json.loads( nodesStr )
2526 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002527 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002528 except ( TypeError, ValueError ):
2529 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002530 return None
andrewonlab7c211572014-10-15 16:45:20 -04002531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002532 main.log.error( self.name + ": EOF exception found" )
2533 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002534 main.cleanup()
2535 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002536 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002537 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002538 main.cleanup()
2539 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002540
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002542 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002543 Return the first device from the devices api whose 'id' contains 'dpid'
2544 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002545 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002546 try:
kelvin8ec71442015-01-15 16:57:00 -08002547 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002548 return None
2549 else:
kelvin8ec71442015-01-15 16:57:00 -08002550 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002551 rawDevices = self.devices()
2552 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002553 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002554 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002555 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2556 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002557 return device
2558 return None
Jon Hallc6793552016-01-19 14:18:37 -08002559 except ( TypeError, ValueError ):
2560 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002561 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002562 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002563 main.log.error( self.name + ": EOF exception found" )
2564 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002565 main.cleanup()
2566 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002567 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002568 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002569 main.cleanup()
2570 main.exit()
2571
kelvin-onlabd3b64892015-01-20 13:26:24 -08002572 def checkStatus( self, ip, numoswitch, numolink, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002573 """
Jon Hallefbd9792015-03-05 16:11:36 -08002574 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002575 supplied values. By default this will report to main.log, but the
Jon Hallefbd9792015-03-05 16:11:36 -08002576 log level can be specified.
kelvin8ec71442015-01-15 16:57:00 -08002577
Jon Hall42db6dc2014-10-24 19:03:48 -04002578 Params: ip = ip used for the onos cli
2579 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002580 numolink = expected number of links
kelvin-onlabd3b64892015-01-20 13:26:24 -08002581 logLevel = level to log to. Currently accepts
2582 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002583
2584
kelvin-onlabd3b64892015-01-20 13:26:24 -08002585 logLevel can
Jon Hall42db6dc2014-10-24 19:03:48 -04002586
Jon Hallefbd9792015-03-05 16:11:36 -08002587 Returns: main.TRUE if the number of switches and links are correct,
2588 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002589 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002590 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002592 topology = self.getTopology( ip )
Jon Hall42db6dc2014-10-24 19:03:48 -04002593 if topology == {}:
2594 return main.ERROR
2595 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002596 # Is the number of switches is what we expected
2597 devices = topology.get( 'devices', False )
2598 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002599 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002600 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002601 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002602 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002603 linkCheck = ( int( links ) == int( numolink ) )
2604 if ( switchCheck and linkCheck ):
kelvin8ec71442015-01-15 16:57:00 -08002605 # We expected the correct numbers
Jon Hallefbd9792015-03-05 16:11:36 -08002606 output += "The number of links and switches match " +\
2607 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002608 result = main.TRUE
2609 else:
Jon Hallefbd9792015-03-05 16:11:36 -08002610 output += "The number of links and switches does not match " +\
2611 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002612 result = main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08002613 output = output + "\n ONOS sees %i devices (%i expected) \
2614 and %i links (%i expected)" % (
2615 int( devices ), int( numoswitch ), int( links ),
2616 int( numolink ) )
2617 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002618 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002619 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002620 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002621 else:
Jon Hall390696c2015-05-05 17:13:41 -07002622 main.log.info( self.name + ": " + output )
kelvin8ec71442015-01-15 16:57:00 -08002623 return result
Jon Halld4d4b372015-01-28 16:02:41 -08002624 except TypeError:
2625 main.log.exception( self.name + ": Object not as expected" )
2626 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04002627 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002628 main.log.error( self.name + ": EOF exception found" )
2629 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002630 main.cleanup()
2631 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002632 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002633 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002634 main.cleanup()
2635 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002636
kelvin-onlabd3b64892015-01-20 13:26:24 -08002637 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002638 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002639 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 deviceId must be the id of a device as seen in the onos devices command
2641 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002642 role must be either master, standby, or none
2643
Jon Halle3f39ff2015-01-13 11:50:53 -08002644 Returns:
2645 main.TRUE or main.FALSE based on argument verification and
2646 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002647 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002648 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002649 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002650 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002651 cmdStr = "device-role " +\
2652 str( deviceId ) + " " +\
2653 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002654 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002655 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002656 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002657 if re.search( "Error", handle ):
2658 # end color output to escape any colours
2659 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002660 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002661 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002662 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002663 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002664 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002665 main.log.error( "Invalid 'role' given to device_role(). " +
2666 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002667 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002668 except AssertionError:
2669 main.log.exception( "" )
2670 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002671 except TypeError:
2672 main.log.exception( self.name + ": Object not as expected" )
2673 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002675 main.log.error( self.name + ": EOF exception found" )
2676 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002677 main.cleanup()
2678 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002679 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002680 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002681 main.cleanup()
2682 main.exit()
2683
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002685 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002686 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002687 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002688 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002689 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002690 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002691 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002693 cmdStr += " -j"
2694 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002695 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002696 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002697 except AssertionError:
2698 main.log.exception( "" )
2699 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002700 except TypeError:
2701 main.log.exception( self.name + ": Object not as expected" )
2702 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002704 main.log.error( self.name + ": EOF exception found" )
2705 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002706 main.cleanup()
2707 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002708 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002709 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002710 main.cleanup()
2711 main.exit()
2712
kelvin-onlabd3b64892015-01-20 13:26:24 -08002713 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002714 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002715 CLI command to get the current leader for the Election test application
2716 NOTE: Requires installation of the onos-app-election feature
2717 Returns: Node IP of the leader if one exists
2718 None if none exists
2719 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002720 """
Jon Hall94fd0472014-12-08 11:52:42 -08002721 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002722 cmdStr = "election-test-leader"
2723 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002724 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002725 # Leader
2726 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002727 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002728 nodeSearch = re.search( leaderPattern, response )
2729 if nodeSearch:
2730 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002731 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002732 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002733 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002734 # no leader
2735 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002736 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002737 nullSearch = re.search( nullPattern, response )
2738 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002739 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002740 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002741 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002742 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002743 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002744 if re.search( errorPattern, response ):
2745 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002746 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002747 return main.FALSE
2748 else:
Jon Hall390696c2015-05-05 17:13:41 -07002749 main.log.error( "Error in electionTestLeader on " + self.name +
2750 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002751 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002752 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002753 except AssertionError:
2754 main.log.exception( "" )
2755 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002756 except TypeError:
2757 main.log.exception( self.name + ": Object not as expected" )
2758 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002760 main.log.error( self.name + ": EOF exception found" )
2761 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002762 main.cleanup()
2763 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002764 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002765 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002766 main.cleanup()
2767 main.exit()
2768
kelvin-onlabd3b64892015-01-20 13:26:24 -08002769 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002770 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002771 CLI command to run for leadership of the Election test application.
2772 NOTE: Requires installation of the onos-app-election feature
2773 Returns: Main.TRUE on success
2774 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002775 """
Jon Hall94fd0472014-12-08 11:52:42 -08002776 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002777 cmdStr = "election-test-run"
2778 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002779 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002780 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002781 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002782 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002783 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002784 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002785 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002786 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002787 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002788 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002789 errorPattern = "Command\snot\sfound"
2790 if re.search( errorPattern, response ):
2791 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002792 return main.FALSE
2793 else:
Jon Hall390696c2015-05-05 17:13:41 -07002794 main.log.error( "Error in electionTestRun on " + self.name +
2795 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002796 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002797 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002798 except AssertionError:
2799 main.log.exception( "" )
2800 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002801 except TypeError:
2802 main.log.exception( self.name + ": Object not as expected" )
2803 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002804 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002805 main.log.error( self.name + ": EOF exception found" )
2806 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002807 main.cleanup()
2808 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002809 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002810 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002811 main.cleanup()
2812 main.exit()
2813
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002815 """
Jon Hall94fd0472014-12-08 11:52:42 -08002816 * CLI command to withdraw the local node from leadership election for
2817 * the Election test application.
2818 #NOTE: Requires installation of the onos-app-election feature
2819 Returns: Main.TRUE on success
2820 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002821 """
Jon Hall94fd0472014-12-08 11:52:42 -08002822 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002823 cmdStr = "election-test-withdraw"
2824 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002825 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002826 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002827 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002828 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002829 if re.search( successPattern, response ):
2830 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002831 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002832 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002833 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002834 errorPattern = "Command\snot\sfound"
2835 if re.search( errorPattern, response ):
2836 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002837 return main.FALSE
2838 else:
Jon Hall390696c2015-05-05 17:13:41 -07002839 main.log.error( "Error in electionTestWithdraw on " +
2840 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002841 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002842 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002843 except AssertionError:
2844 main.log.exception( "" )
2845 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002846 except TypeError:
2847 main.log.exception( self.name + ": Object not as expected" )
2848 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002850 main.log.error( self.name + ": EOF exception found" )
2851 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002852 main.cleanup()
2853 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002855 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002856 main.cleanup()
2857 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002858
kelvin8ec71442015-01-15 16:57:00 -08002859 def getDevicePortsEnabledCount( self, dpid ):
2860 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002861 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002862 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002863 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002864 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002865 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2866 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002867 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002868 if re.search( "No such device", output ):
2869 main.log.error( "Error in getting ports" )
2870 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002871 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002872 return output
Jon Hallc6793552016-01-19 14:18:37 -08002873 except AssertionError:
2874 main.log.exception( "" )
2875 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002876 except TypeError:
2877 main.log.exception( self.name + ": Object not as expected" )
2878 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002880 main.log.error( self.name + ": EOF exception found" )
2881 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002882 main.cleanup()
2883 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002884 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002885 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002886 main.cleanup()
2887 main.exit()
2888
kelvin8ec71442015-01-15 16:57:00 -08002889 def getDeviceLinksActiveCount( self, dpid ):
2890 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002891 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002892 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002893 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002894 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002895 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2896 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002897 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002898 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002899 main.log.error( "Error in getting ports " )
2900 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002901 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002902 return output
Jon Hallc6793552016-01-19 14:18:37 -08002903 except AssertionError:
2904 main.log.exception( "" )
2905 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002906 except TypeError:
2907 main.log.exception( self.name + ": Object not as expected" )
2908 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002909 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002910 main.log.error( self.name + ": EOF exception found" )
2911 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002912 main.cleanup()
2913 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002914 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002915 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002916 main.cleanup()
2917 main.exit()
2918
kelvin8ec71442015-01-15 16:57:00 -08002919 def getAllIntentIds( self ):
2920 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002921 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002922 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002923 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002924 cmdStr = "onos:intents | grep id="
2925 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002926 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002927 if re.search( "Error", output ):
2928 main.log.error( "Error in getting ports" )
2929 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002930 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002931 return output
Jon Hallc6793552016-01-19 14:18:37 -08002932 except AssertionError:
2933 main.log.exception( "" )
2934 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002935 except TypeError:
2936 main.log.exception( self.name + ": Object not as expected" )
2937 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002938 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002939 main.log.error( self.name + ": EOF exception found" )
2940 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002941 main.cleanup()
2942 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002943 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002944 main.log.exception( self.name + ": Uncaught exception!" )
2945 main.cleanup()
2946 main.exit()
2947
Jon Hall73509952015-02-24 16:42:56 -08002948 def intentSummary( self ):
2949 """
Jon Hallefbd9792015-03-05 16:11:36 -08002950 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002951 """
2952 try:
2953 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002954 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002955 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002956 states.append( intent.get( 'state', None ) )
2957 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002958 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002959 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002960 except ( TypeError, ValueError ):
2961 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002962 return None
2963 except pexpect.EOF:
2964 main.log.error( self.name + ": EOF exception found" )
2965 main.log.error( self.name + ": " + self.handle.before )
2966 main.cleanup()
2967 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002968 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002969 main.log.exception( self.name + ": Uncaught exception!" )
2970 main.cleanup()
2971 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002972
Jon Hall61282e32015-03-19 11:34:11 -07002973 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08002974 """
2975 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07002976 Optional argument:
2977 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08002978 """
Jon Hall63604932015-02-26 17:09:50 -08002979 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002980 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07002981 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002982 cmdStr += " -j"
2983 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002984 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07002985 return output
Jon Hallc6793552016-01-19 14:18:37 -08002986 except AssertionError:
2987 main.log.exception( "" )
2988 return None
Jon Hall63604932015-02-26 17:09:50 -08002989 except TypeError:
2990 main.log.exception( self.name + ": Object not as expected" )
2991 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002992 except pexpect.EOF:
2993 main.log.error( self.name + ": EOF exception found" )
2994 main.log.error( self.name + ": " + self.handle.before )
2995 main.cleanup()
2996 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07002997 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08002998 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002999 main.cleanup()
3000 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003001
acsmarsa4a4d1e2015-07-10 16:01:24 -07003002 def leaderCandidates( self, jsonFormat=True ):
3003 """
3004 Returns the output of the leaders -c command.
3005 Optional argument:
3006 * jsonFormat - boolean indicating if you want output in json
3007 """
3008 try:
3009 cmdStr = "onos:leaders -c"
3010 if jsonFormat:
3011 cmdStr += " -j"
3012 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003013 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003014 return output
Jon Hallc6793552016-01-19 14:18:37 -08003015 except AssertionError:
3016 main.log.exception( "" )
3017 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003018 except TypeError:
3019 main.log.exception( self.name + ": Object not as expected" )
3020 return None
3021 except pexpect.EOF:
3022 main.log.error( self.name + ": EOF exception found" )
3023 main.log.error( self.name + ": " + self.handle.before )
3024 main.cleanup()
3025 main.exit()
3026 except Exception:
3027 main.log.exception( self.name + ": Uncaught exception!" )
3028 main.cleanup()
3029 main.exit()
3030
Jon Hallc6793552016-01-19 14:18:37 -08003031 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003032 """
3033 Returns a list in format [leader,candidate1,candidate2,...] for a given
3034 topic parameter and an empty list if the topic doesn't exist
3035 If no leader is elected leader in the returned list will be "none"
3036 Returns None if there is a type error processing the json object
3037 """
3038 try:
Jon Hall6e709752016-02-01 13:38:46 -08003039 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003040 rawOutput = self.sendline( cmdStr )
3041 assert "Command not found:" not in rawOutput, rawOutput
3042 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003043 results = []
3044 for dict in output:
3045 if dict["topic"] == topic:
3046 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003047 candidates = re.split( ", ", dict["candidates"][1:-1] )
3048 results.append( leader )
3049 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003050 return results
Jon Hallc6793552016-01-19 14:18:37 -08003051 except AssertionError:
3052 main.log.exception( "" )
3053 return None
3054 except ( TypeError, ValueError ):
3055 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003056 return None
3057 except pexpect.EOF:
3058 main.log.error( self.name + ": EOF exception found" )
3059 main.log.error( self.name + ": " + self.handle.before )
3060 main.cleanup()
3061 main.exit()
3062 except Exception:
3063 main.log.exception( self.name + ": Uncaught exception!" )
3064 main.cleanup()
3065 main.exit()
3066
Jon Hall61282e32015-03-19 11:34:11 -07003067 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003068 """
3069 Returns the output of the intent Pending map.
3070 """
Jon Hall63604932015-02-26 17:09:50 -08003071 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003072 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003073 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003074 cmdStr += " -j"
3075 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003076 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003077 return output
Jon Hallc6793552016-01-19 14:18:37 -08003078 except AssertionError:
3079 main.log.exception( "" )
3080 return None
Jon Hall63604932015-02-26 17:09:50 -08003081 except TypeError:
3082 main.log.exception( self.name + ": Object not as expected" )
3083 return None
3084 except pexpect.EOF:
3085 main.log.error( self.name + ": EOF exception found" )
3086 main.log.error( self.name + ": " + self.handle.before )
3087 main.cleanup()
3088 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003089 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003090 main.log.exception( self.name + ": Uncaught exception!" )
3091 main.cleanup()
3092 main.exit()
3093
Jon Hall61282e32015-03-19 11:34:11 -07003094 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003095 """
3096 Returns the output of the raft partitions command for ONOS.
3097 """
Jon Hall61282e32015-03-19 11:34:11 -07003098 # Sample JSON
3099 # {
3100 # "leader": "tcp://10.128.30.11:7238",
3101 # "members": [
3102 # "tcp://10.128.30.11:7238",
3103 # "tcp://10.128.30.17:7238",
3104 # "tcp://10.128.30.13:7238",
3105 # ],
3106 # "name": "p1",
3107 # "term": 3
3108 # },
Jon Hall63604932015-02-26 17:09:50 -08003109 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003110 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003111 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003112 cmdStr += " -j"
3113 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003114 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003115 return output
Jon Hallc6793552016-01-19 14:18:37 -08003116 except AssertionError:
3117 main.log.exception( "" )
3118 return None
Jon Hall63604932015-02-26 17:09:50 -08003119 except TypeError:
3120 main.log.exception( self.name + ": Object not as expected" )
3121 return None
3122 except pexpect.EOF:
3123 main.log.error( self.name + ": EOF exception found" )
3124 main.log.error( self.name + ": " + self.handle.before )
3125 main.cleanup()
3126 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003127 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003128 main.log.exception( self.name + ": Uncaught exception!" )
3129 main.cleanup()
3130 main.exit()
3131
Jon Hallbe379602015-03-24 13:39:32 -07003132 def apps( self, jsonFormat=True ):
3133 """
3134 Returns the output of the apps command for ONOS. This command lists
3135 information about installed ONOS applications
3136 """
3137 # Sample JSON object
3138 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3139 # "description":"ONOS OpenFlow protocol southbound providers",
3140 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3141 # "features":"[onos-openflow]","state":"ACTIVE"}]
3142 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003143 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003144 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003145 cmdStr += " -j"
3146 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003147 assert "Command not found:" not in output, output
3148 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003149 return output
Jon Hallbe379602015-03-24 13:39:32 -07003150 # FIXME: look at specific exceptions/Errors
3151 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003152 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003153 return None
3154 except TypeError:
3155 main.log.exception( self.name + ": Object not as expected" )
3156 return None
3157 except pexpect.EOF:
3158 main.log.error( self.name + ": EOF exception found" )
3159 main.log.error( self.name + ": " + self.handle.before )
3160 main.cleanup()
3161 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003162 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003163 main.log.exception( self.name + ": Uncaught exception!" )
3164 main.cleanup()
3165 main.exit()
3166
Jon Hall146f1522015-03-24 15:33:24 -07003167 def appStatus( self, appName ):
3168 """
3169 Uses the onos:apps cli command to return the status of an application.
3170 Returns:
3171 "ACTIVE" - If app is installed and activated
3172 "INSTALLED" - If app is installed and deactivated
3173 "UNINSTALLED" - If app is not installed
3174 None - on error
3175 """
Jon Hall146f1522015-03-24 15:33:24 -07003176 try:
3177 if not isinstance( appName, types.StringType ):
3178 main.log.error( self.name + ".appStatus(): appName must be" +
3179 " a string" )
3180 return None
3181 output = self.apps( jsonFormat=True )
3182 appsJson = json.loads( output )
3183 state = None
3184 for app in appsJson:
3185 if appName == app.get('name'):
3186 state = app.get('state')
3187 break
3188 if state == "ACTIVE" or state == "INSTALLED":
3189 return state
3190 elif state is None:
3191 return "UNINSTALLED"
3192 elif state:
3193 main.log.error( "Unexpected state from 'onos:apps': " +
3194 str( state ) )
3195 return state
Jon Hallc6793552016-01-19 14:18:37 -08003196 except ( TypeError, ValueError ):
3197 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003198 return None
3199 except pexpect.EOF:
3200 main.log.error( self.name + ": EOF exception found" )
3201 main.log.error( self.name + ": " + self.handle.before )
3202 main.cleanup()
3203 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003204 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003205 main.log.exception( self.name + ": Uncaught exception!" )
3206 main.cleanup()
3207 main.exit()
3208
Jon Hallbe379602015-03-24 13:39:32 -07003209 def app( self, appName, option ):
3210 """
3211 Interacts with the app command for ONOS. This command manages
3212 application inventory.
3213 """
Jon Hallbe379602015-03-24 13:39:32 -07003214 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003215 # Validate argument types
3216 valid = True
3217 if not isinstance( appName, types.StringType ):
3218 main.log.error( self.name + ".app(): appName must be a " +
3219 "string" )
3220 valid = False
3221 if not isinstance( option, types.StringType ):
3222 main.log.error( self.name + ".app(): option must be a string" )
3223 valid = False
3224 if not valid:
3225 return main.FALSE
3226 # Validate Option
3227 option = option.lower()
3228 # NOTE: Install may become a valid option
3229 if option == "activate":
3230 pass
3231 elif option == "deactivate":
3232 pass
3233 elif option == "uninstall":
3234 pass
3235 else:
3236 # Invalid option
3237 main.log.error( "The ONOS app command argument only takes " +
3238 "the values: (activate|deactivate|uninstall)" +
3239 "; was given '" + option + "'")
3240 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003241 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003242 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003243 if "Error executing command" in output:
3244 main.log.error( "Error in processing onos:app command: " +
3245 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003246 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003247 elif "No such application" in output:
3248 main.log.error( "The application '" + appName +
3249 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003250 return main.FALSE
3251 elif "Command not found:" in output:
3252 main.log.error( "Error in processing onos:app command: " +
3253 str( output ) )
3254 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003255 elif "Unsupported command:" in output:
3256 main.log.error( "Incorrect command given to 'app': " +
3257 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003258 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003259 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003260 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003261 return main.TRUE
3262 except TypeError:
3263 main.log.exception( self.name + ": Object not as expected" )
3264 return main.ERROR
3265 except pexpect.EOF:
3266 main.log.error( self.name + ": EOF exception found" )
3267 main.log.error( self.name + ": " + self.handle.before )
3268 main.cleanup()
3269 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003270 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003271 main.log.exception( self.name + ": Uncaught exception!" )
3272 main.cleanup()
3273 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003274
Jon Hallbd16b922015-03-26 17:53:15 -07003275 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003276 """
3277 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003278 appName is the hierarchical app name, not the feature name
3279 If check is True, method will check the status of the app after the
3280 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003281 Returns main.TRUE if the command was successfully sent
3282 main.FALSE if the cli responded with an error or given
3283 incorrect input
3284 """
3285 try:
3286 if not isinstance( appName, types.StringType ):
3287 main.log.error( self.name + ".activateApp(): appName must be" +
3288 " a string" )
3289 return main.FALSE
3290 status = self.appStatus( appName )
3291 if status == "INSTALLED":
3292 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003293 if check and response == main.TRUE:
3294 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003295 status = self.appStatus( appName )
3296 if status == "ACTIVE":
3297 return main.TRUE
3298 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003299 main.log.debug( "The state of application " +
3300 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003301 time.sleep( 1 )
3302 return main.FALSE
3303 else: # not 'check' or command didn't succeed
3304 return response
Jon Hall146f1522015-03-24 15:33:24 -07003305 elif status == "ACTIVE":
3306 return main.TRUE
3307 elif status == "UNINSTALLED":
3308 main.log.error( self.name + ": Tried to activate the " +
3309 "application '" + appName + "' which is not " +
3310 "installed." )
3311 else:
3312 main.log.error( "Unexpected return value from appStatus: " +
3313 str( status ) )
3314 return main.ERROR
3315 except TypeError:
3316 main.log.exception( self.name + ": Object not as expected" )
3317 return main.ERROR
3318 except pexpect.EOF:
3319 main.log.error( self.name + ": EOF exception found" )
3320 main.log.error( self.name + ": " + self.handle.before )
3321 main.cleanup()
3322 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003323 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003324 main.log.exception( self.name + ": Uncaught exception!" )
3325 main.cleanup()
3326 main.exit()
3327
Jon Hallbd16b922015-03-26 17:53:15 -07003328 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003329 """
3330 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003331 appName is the hierarchical app name, not the feature name
3332 If check is True, method will check the status of the app after the
3333 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003334 Returns main.TRUE if the command was successfully sent
3335 main.FALSE if the cli responded with an error or given
3336 incorrect input
3337 """
3338 try:
3339 if not isinstance( appName, types.StringType ):
3340 main.log.error( self.name + ".deactivateApp(): appName must " +
3341 "be a string" )
3342 return main.FALSE
3343 status = self.appStatus( appName )
3344 if status == "INSTALLED":
3345 return main.TRUE
3346 elif status == "ACTIVE":
3347 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003348 if check and response == main.TRUE:
3349 for i in range(10): # try 10 times then give up
3350 status = self.appStatus( appName )
3351 if status == "INSTALLED":
3352 return main.TRUE
3353 else:
3354 time.sleep( 1 )
3355 return main.FALSE
3356 else: # not check or command didn't succeed
3357 return response
Jon Hall146f1522015-03-24 15:33:24 -07003358 elif status == "UNINSTALLED":
3359 main.log.warn( self.name + ": Tried to deactivate the " +
3360 "application '" + appName + "' which is not " +
3361 "installed." )
3362 return main.TRUE
3363 else:
3364 main.log.error( "Unexpected return value from appStatus: " +
3365 str( status ) )
3366 return main.ERROR
3367 except TypeError:
3368 main.log.exception( self.name + ": Object not as expected" )
3369 return main.ERROR
3370 except pexpect.EOF:
3371 main.log.error( self.name + ": EOF exception found" )
3372 main.log.error( self.name + ": " + self.handle.before )
3373 main.cleanup()
3374 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003375 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003376 main.log.exception( self.name + ": Uncaught exception!" )
3377 main.cleanup()
3378 main.exit()
3379
Jon Hallbd16b922015-03-26 17:53:15 -07003380 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003381 """
3382 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003383 appName is the hierarchical app name, not the feature name
3384 If check is True, method will check the status of the app after the
3385 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003386 Returns main.TRUE if the command was successfully sent
3387 main.FALSE if the cli responded with an error or given
3388 incorrect input
3389 """
3390 # TODO: check with Thomas about the state machine for apps
3391 try:
3392 if not isinstance( appName, types.StringType ):
3393 main.log.error( self.name + ".uninstallApp(): appName must " +
3394 "be a string" )
3395 return main.FALSE
3396 status = self.appStatus( appName )
3397 if status == "INSTALLED":
3398 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003399 if check and response == main.TRUE:
3400 for i in range(10): # try 10 times then give up
3401 status = self.appStatus( appName )
3402 if status == "UNINSTALLED":
3403 return main.TRUE
3404 else:
3405 time.sleep( 1 )
3406 return main.FALSE
3407 else: # not check or command didn't succeed
3408 return response
Jon Hall146f1522015-03-24 15:33:24 -07003409 elif status == "ACTIVE":
3410 main.log.warn( self.name + ": Tried to uninstall the " +
3411 "application '" + appName + "' which is " +
3412 "currently active." )
3413 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003414 if check and response == main.TRUE:
3415 for i in range(10): # try 10 times then give up
3416 status = self.appStatus( appName )
3417 if status == "UNINSTALLED":
3418 return main.TRUE
3419 else:
3420 time.sleep( 1 )
3421 return main.FALSE
3422 else: # not check or command didn't succeed
3423 return response
Jon Hall146f1522015-03-24 15:33:24 -07003424 elif status == "UNINSTALLED":
3425 return main.TRUE
3426 else:
3427 main.log.error( "Unexpected return value from appStatus: " +
3428 str( status ) )
3429 return main.ERROR
3430 except TypeError:
3431 main.log.exception( self.name + ": Object not as expected" )
3432 return main.ERROR
3433 except pexpect.EOF:
3434 main.log.error( self.name + ": EOF exception found" )
3435 main.log.error( self.name + ": " + self.handle.before )
3436 main.cleanup()
3437 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003438 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003439 main.log.exception( self.name + ": Uncaught exception!" )
3440 main.cleanup()
3441 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003442
3443 def appIDs( self, jsonFormat=True ):
3444 """
3445 Show the mappings between app id and app names given by the 'app-ids'
3446 cli command
3447 """
3448 try:
3449 cmdStr = "app-ids"
3450 if jsonFormat:
3451 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003452 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003453 assert "Command not found:" not in output, output
3454 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003455 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003456 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003457 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003458 return None
3459 except TypeError:
3460 main.log.exception( self.name + ": Object not as expected" )
3461 return None
3462 except pexpect.EOF:
3463 main.log.error( self.name + ": EOF exception found" )
3464 main.log.error( self.name + ": " + self.handle.before )
3465 main.cleanup()
3466 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003467 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003468 main.log.exception( self.name + ": Uncaught exception!" )
3469 main.cleanup()
3470 main.exit()
3471
3472 def appToIDCheck( self ):
3473 """
3474 This method will check that each application's ID listed in 'apps' is
3475 the same as the ID listed in 'app-ids'. The check will also check that
3476 there are no duplicate IDs issued. Note that an app ID should be
3477 a globaly unique numerical identifier for app/app-like features. Once
3478 an ID is registered, the ID is never freed up so that if an app is
3479 reinstalled it will have the same ID.
3480
3481 Returns: main.TRUE if the check passes and
3482 main.FALSE if the check fails or
3483 main.ERROR if there is some error in processing the test
3484 """
3485 try:
Jon Hall390696c2015-05-05 17:13:41 -07003486 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003487 rawJson = self.appIDs( jsonFormat=True )
3488 if rawJson:
3489 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003490 else:
Jon Hallc6793552016-01-19 14:18:37 -08003491 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003492 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003493 rawJson = self.apps( jsonFormat=True )
3494 if rawJson:
3495 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003496 else:
Jon Hallc6793552016-01-19 14:18:37 -08003497 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003498 bail = True
3499 if bail:
3500 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003501 result = main.TRUE
3502 for app in apps:
3503 appID = app.get( 'id' )
3504 if appID is None:
3505 main.log.error( "Error parsing app: " + str( app ) )
3506 result = main.FALSE
3507 appName = app.get( 'name' )
3508 if appName is None:
3509 main.log.error( "Error parsing app: " + str( app ) )
3510 result = main.FALSE
3511 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003512 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003513 # main.log.debug( "Comparing " + str( app ) + " to " +
3514 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003515 if not current: # if ids doesn't have this id
3516 result = main.FALSE
3517 main.log.error( "'app-ids' does not have the ID for " +
3518 str( appName ) + " that apps does." )
3519 elif len( current ) > 1:
3520 # there is more than one app with this ID
3521 result = main.FALSE
3522 # We will log this later in the method
3523 elif not current[0][ 'name' ] == appName:
3524 currentName = current[0][ 'name' ]
3525 result = main.FALSE
3526 main.log.error( "'app-ids' has " + str( currentName ) +
3527 " registered under id:" + str( appID ) +
3528 " but 'apps' has " + str( appName ) )
3529 else:
3530 pass # id and name match!
3531 # now make sure that app-ids has no duplicates
3532 idsList = []
3533 namesList = []
3534 for item in ids:
3535 idsList.append( item[ 'id' ] )
3536 namesList.append( item[ 'name' ] )
3537 if len( idsList ) != len( set( idsList ) ) or\
3538 len( namesList ) != len( set( namesList ) ):
3539 main.log.error( "'app-ids' has some duplicate entries: \n"
3540 + json.dumps( ids,
3541 sort_keys=True,
3542 indent=4,
3543 separators=( ',', ': ' ) ) )
3544 result = main.FALSE
3545 return result
Jon Hallc6793552016-01-19 14:18:37 -08003546 except ( TypeError, ValueError ):
3547 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003548 return main.ERROR
3549 except pexpect.EOF:
3550 main.log.error( self.name + ": EOF exception found" )
3551 main.log.error( self.name + ": " + self.handle.before )
3552 main.cleanup()
3553 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003554 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003555 main.log.exception( self.name + ": Uncaught exception!" )
3556 main.cleanup()
3557 main.exit()
3558
Jon Hallfb760a02015-04-13 15:35:03 -07003559 def getCfg( self, component=None, propName=None, short=False,
3560 jsonFormat=True ):
3561 """
3562 Get configuration settings from onos cli
3563 Optional arguments:
3564 component - Optionally only list configurations for a specific
3565 component. If None, all components with configurations
3566 are displayed. Case Sensitive string.
3567 propName - If component is specified, propName option will show
3568 only this specific configuration from that component.
3569 Case Sensitive string.
3570 jsonFormat - Returns output as json. Note that this will override
3571 the short option
3572 short - Short, less verbose, version of configurations.
3573 This is overridden by the json option
3574 returns:
3575 Output from cli as a string or None on error
3576 """
3577 try:
3578 baseStr = "cfg"
3579 cmdStr = " get"
3580 componentStr = ""
3581 if component:
3582 componentStr += " " + component
3583 if propName:
3584 componentStr += " " + propName
3585 if jsonFormat:
3586 baseStr += " -j"
3587 elif short:
3588 baseStr += " -s"
3589 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003590 assert "Command not found:" not in output, output
3591 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003592 return output
3593 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003594 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003595 return None
3596 except TypeError:
3597 main.log.exception( self.name + ": Object not as expected" )
3598 return None
3599 except pexpect.EOF:
3600 main.log.error( self.name + ": EOF exception found" )
3601 main.log.error( self.name + ": " + self.handle.before )
3602 main.cleanup()
3603 main.exit()
3604 except Exception:
3605 main.log.exception( self.name + ": Uncaught exception!" )
3606 main.cleanup()
3607 main.exit()
3608
3609 def setCfg( self, component, propName, value=None, check=True ):
3610 """
3611 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003612 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003613 component - The case sensitive name of the component whose
3614 property is to be set
3615 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003616 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003617 value - The value to set the property to. If None, will unset the
3618 property and revert it to it's default value(if applicable)
3619 check - Boolean, Check whether the option was successfully set this
3620 only applies when a value is given.
3621 returns:
3622 main.TRUE on success or main.FALSE on failure. If check is False,
3623 will return main.TRUE unless there is an error
3624 """
3625 try:
3626 baseStr = "cfg"
3627 cmdStr = " set " + str( component ) + " " + str( propName )
3628 if value is not None:
3629 cmdStr += " " + str( value )
3630 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003631 assert "Command not found:" not in output, output
3632 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003633 if value and check:
3634 results = self.getCfg( component=str( component ),
3635 propName=str( propName ),
3636 jsonFormat=True )
3637 # Check if current value is what we just set
3638 try:
3639 jsonOutput = json.loads( results )
3640 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003641 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003642 main.log.exception( "Error parsing cfg output" )
3643 main.log.error( "output:" + repr( results ) )
3644 return main.FALSE
3645 if current == str( value ):
3646 return main.TRUE
3647 return main.FALSE
3648 return main.TRUE
3649 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003650 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003651 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003652 except ( TypeError, ValueError ):
3653 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003654 return main.FALSE
3655 except pexpect.EOF:
3656 main.log.error( self.name + ": EOF exception found" )
3657 main.log.error( self.name + ": " + self.handle.before )
3658 main.cleanup()
3659 main.exit()
3660 except Exception:
3661 main.log.exception( self.name + ": Uncaught exception!" )
3662 main.cleanup()
3663 main.exit()
3664
Jon Hall390696c2015-05-05 17:13:41 -07003665 def setTestAdd( self, setName, values ):
3666 """
3667 CLI command to add elements to a distributed set.
3668 Arguments:
3669 setName - The name of the set to add to.
3670 values - The value(s) to add to the set, space seperated.
3671 Example usages:
3672 setTestAdd( "set1", "a b c" )
3673 setTestAdd( "set2", "1" )
3674 returns:
3675 main.TRUE on success OR
3676 main.FALSE if elements were already in the set OR
3677 main.ERROR on error
3678 """
3679 try:
3680 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3681 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003682 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003683 try:
3684 # TODO: Maybe make this less hardcoded
3685 # ConsistentMap Exceptions
3686 assert "org.onosproject.store.service" not in output
3687 # Node not leader
3688 assert "java.lang.IllegalStateException" not in output
3689 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003690 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003691 "command: " + str( output ) )
3692 retryTime = 30 # Conservative time, given by Madan
3693 main.log.info( "Waiting " + str( retryTime ) +
3694 "seconds before retrying." )
3695 time.sleep( retryTime ) # Due to change in mastership
3696 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003697 assert "Error executing command" not in output
3698 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3699 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3700 main.log.info( self.name + ": " + output )
3701 if re.search( positiveMatch, output):
3702 return main.TRUE
3703 elif re.search( negativeMatch, output):
3704 return main.FALSE
3705 else:
3706 main.log.error( self.name + ": setTestAdd did not" +
3707 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003708 main.log.debug( self.name + " actual: " + repr( output ) )
3709 return main.ERROR
3710 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003711 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003712 return main.ERROR
3713 except TypeError:
3714 main.log.exception( self.name + ": Object not as expected" )
3715 return main.ERROR
3716 except pexpect.EOF:
3717 main.log.error( self.name + ": EOF exception found" )
3718 main.log.error( self.name + ": " + self.handle.before )
3719 main.cleanup()
3720 main.exit()
3721 except Exception:
3722 main.log.exception( self.name + ": Uncaught exception!" )
3723 main.cleanup()
3724 main.exit()
3725
3726 def setTestRemove( self, setName, values, clear=False, retain=False ):
3727 """
3728 CLI command to remove elements from a distributed set.
3729 Required arguments:
3730 setName - The name of the set to remove from.
3731 values - The value(s) to remove from the set, space seperated.
3732 Optional arguments:
3733 clear - Clear all elements from the set
3734 retain - Retain only the given values. (intersection of the
3735 original set and the given set)
3736 returns:
3737 main.TRUE on success OR
3738 main.FALSE if the set was not changed OR
3739 main.ERROR on error
3740 """
3741 try:
3742 cmdStr = "set-test-remove "
3743 if clear:
3744 cmdStr += "-c " + str( setName )
3745 elif retain:
3746 cmdStr += "-r " + str( setName ) + " " + str( values )
3747 else:
3748 cmdStr += str( setName ) + " " + str( values )
3749 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003750 try:
3751 # TODO: Maybe make this less hardcoded
3752 # ConsistentMap Exceptions
3753 assert "org.onosproject.store.service" not in output
3754 # Node not leader
3755 assert "java.lang.IllegalStateException" not in output
3756 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003757 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003758 "command: " + str( output ) )
3759 retryTime = 30 # Conservative time, given by Madan
3760 main.log.info( "Waiting " + str( retryTime ) +
3761 "seconds before retrying." )
3762 time.sleep( retryTime ) # Due to change in mastership
3763 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003764 assert "Command not found:" not in output, output
3765 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003766 main.log.info( self.name + ": " + output )
3767 if clear:
3768 pattern = "Set " + str( setName ) + " cleared"
3769 if re.search( pattern, output ):
3770 return main.TRUE
3771 elif retain:
3772 positivePattern = str( setName ) + " was pruned to contain " +\
3773 "only elements of set \[(.*)\]"
3774 negativePattern = str( setName ) + " was not changed by " +\
3775 "retaining only elements of the set " +\
3776 "\[(.*)\]"
3777 if re.search( positivePattern, output ):
3778 return main.TRUE
3779 elif re.search( negativePattern, output ):
3780 return main.FALSE
3781 else:
3782 positivePattern = "\[(.*)\] was removed from the set " +\
3783 str( setName )
3784 if ( len( values.split() ) == 1 ):
3785 negativePattern = "\[(.*)\] was not in set " +\
3786 str( setName )
3787 else:
3788 negativePattern = "No element of \[(.*)\] was in set " +\
3789 str( setName )
3790 if re.search( positivePattern, output ):
3791 return main.TRUE
3792 elif re.search( negativePattern, output ):
3793 return main.FALSE
3794 main.log.error( self.name + ": setTestRemove did not" +
3795 " match expected output" )
3796 main.log.debug( self.name + " expected: " + pattern )
3797 main.log.debug( self.name + " actual: " + repr( output ) )
3798 return main.ERROR
3799 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003800 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003801 return main.ERROR
3802 except TypeError:
3803 main.log.exception( self.name + ": Object not as expected" )
3804 return main.ERROR
3805 except pexpect.EOF:
3806 main.log.error( self.name + ": EOF exception found" )
3807 main.log.error( self.name + ": " + self.handle.before )
3808 main.cleanup()
3809 main.exit()
3810 except Exception:
3811 main.log.exception( self.name + ": Uncaught exception!" )
3812 main.cleanup()
3813 main.exit()
3814
3815 def setTestGet( self, setName, values="" ):
3816 """
3817 CLI command to get the elements in a distributed set.
3818 Required arguments:
3819 setName - The name of the set to remove from.
3820 Optional arguments:
3821 values - The value(s) to check if in the set, space seperated.
3822 returns:
3823 main.ERROR on error OR
3824 A list of elements in the set if no optional arguments are
3825 supplied OR
3826 A tuple containing the list then:
3827 main.FALSE if the given values are not in the set OR
3828 main.TRUE if the given values are in the set OR
3829 """
3830 try:
3831 values = str( values ).strip()
3832 setName = str( setName ).strip()
3833 length = len( values.split() )
3834 containsCheck = None
3835 # Patterns to match
3836 setPattern = "\[(.*)\]"
3837 pattern = "Items in set " + setName + ":\n" + setPattern
3838 containsTrue = "Set " + setName + " contains the value " + values
3839 containsFalse = "Set " + setName + " did not contain the value " +\
3840 values
3841 containsAllTrue = "Set " + setName + " contains the the subset " +\
3842 setPattern
3843 containsAllFalse = "Set " + setName + " did not contain the the" +\
3844 " subset " + setPattern
3845
3846 cmdStr = "set-test-get "
3847 cmdStr += setName + " " + values
3848 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003849 try:
3850 # TODO: Maybe make this less hardcoded
3851 # ConsistentMap Exceptions
3852 assert "org.onosproject.store.service" not in output
3853 # Node not leader
3854 assert "java.lang.IllegalStateException" not in output
3855 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003856 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003857 "command: " + str( output ) )
3858 retryTime = 30 # Conservative time, given by Madan
3859 main.log.info( "Waiting " + str( retryTime ) +
3860 "seconds before retrying." )
3861 time.sleep( retryTime ) # Due to change in mastership
3862 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003863 assert "Command not found:" not in output, output
3864 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003865 main.log.info( self.name + ": " + output )
3866
3867 if length == 0:
3868 match = re.search( pattern, output )
3869 else: # if given values
3870 if length == 1: # Contains output
3871 patternTrue = pattern + "\n" + containsTrue
3872 patternFalse = pattern + "\n" + containsFalse
3873 else: # ContainsAll output
3874 patternTrue = pattern + "\n" + containsAllTrue
3875 patternFalse = pattern + "\n" + containsAllFalse
3876 matchTrue = re.search( patternTrue, output )
3877 matchFalse = re.search( patternFalse, output )
3878 if matchTrue:
3879 containsCheck = main.TRUE
3880 match = matchTrue
3881 elif matchFalse:
3882 containsCheck = main.FALSE
3883 match = matchFalse
3884 else:
3885 main.log.error( self.name + " setTestGet did not match " +\
3886 "expected output" )
3887 main.log.debug( self.name + " expected: " + pattern )
3888 main.log.debug( self.name + " actual: " + repr( output ) )
3889 match = None
3890 if match:
3891 setMatch = match.group( 1 )
3892 if setMatch == '':
3893 setList = []
3894 else:
3895 setList = setMatch.split( ", " )
3896 if length > 0:
3897 return ( setList, containsCheck )
3898 else:
3899 return setList
3900 else: # no match
3901 main.log.error( self.name + ": setTestGet did not" +
3902 " match expected output" )
3903 main.log.debug( self.name + " expected: " + pattern )
3904 main.log.debug( self.name + " actual: " + repr( output ) )
3905 return main.ERROR
3906 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003907 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003908 return main.ERROR
3909 except TypeError:
3910 main.log.exception( self.name + ": Object not as expected" )
3911 return main.ERROR
3912 except pexpect.EOF:
3913 main.log.error( self.name + ": EOF exception found" )
3914 main.log.error( self.name + ": " + self.handle.before )
3915 main.cleanup()
3916 main.exit()
3917 except Exception:
3918 main.log.exception( self.name + ": Uncaught exception!" )
3919 main.cleanup()
3920 main.exit()
3921
3922 def setTestSize( self, setName ):
3923 """
3924 CLI command to get the elements in a distributed set.
3925 Required arguments:
3926 setName - The name of the set to remove from.
3927 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003928 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003929 None on error
3930 """
3931 try:
3932 # TODO: Should this check against the number of elements returned
3933 # and then return true/false based on that?
3934 setName = str( setName ).strip()
3935 # Patterns to match
3936 setPattern = "\[(.*)\]"
3937 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3938 setPattern
3939 cmdStr = "set-test-get -s "
3940 cmdStr += setName
3941 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003942 try:
3943 # TODO: Maybe make this less hardcoded
3944 # ConsistentMap Exceptions
3945 assert "org.onosproject.store.service" not in output
3946 # Node not leader
3947 assert "java.lang.IllegalStateException" not in output
3948 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003949 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003950 "command: " + str( output ) )
3951 retryTime = 30 # Conservative time, given by Madan
3952 main.log.info( "Waiting " + str( retryTime ) +
3953 "seconds before retrying." )
3954 time.sleep( retryTime ) # Due to change in mastership
3955 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003956 assert "Command not found:" not in output, output
3957 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003958 main.log.info( self.name + ": " + output )
3959 match = re.search( pattern, output )
3960 if match:
3961 setSize = int( match.group( 1 ) )
3962 setMatch = match.group( 2 )
3963 if len( setMatch.split() ) == setSize:
3964 main.log.info( "The size returned by " + self.name +
3965 " matches the number of elements in " +
3966 "the returned set" )
3967 else:
3968 main.log.error( "The size returned by " + self.name +
3969 " does not match the number of " +
3970 "elements in the returned set." )
3971 return setSize
3972 else: # no match
3973 main.log.error( self.name + ": setTestGet did not" +
3974 " match expected output" )
3975 main.log.debug( self.name + " expected: " + pattern )
3976 main.log.debug( self.name + " actual: " + repr( output ) )
3977 return None
3978 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003979 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003980 return None
Jon Hall390696c2015-05-05 17:13:41 -07003981 except TypeError:
3982 main.log.exception( self.name + ": Object not as expected" )
3983 return None
3984 except pexpect.EOF:
3985 main.log.error( self.name + ": EOF exception found" )
3986 main.log.error( self.name + ": " + self.handle.before )
3987 main.cleanup()
3988 main.exit()
3989 except Exception:
3990 main.log.exception( self.name + ": Uncaught exception!" )
3991 main.cleanup()
3992 main.exit()
3993
Jon Hall80daded2015-05-27 16:07:00 -07003994 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07003995 """
3996 Command to list the various counters in the system.
3997 returns:
Jon Hall80daded2015-05-27 16:07:00 -07003998 if jsonFormat, a string of the json object returned by the cli
3999 command
4000 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004001 None on error
4002 """
Jon Hall390696c2015-05-05 17:13:41 -07004003 try:
4004 counters = {}
4005 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004006 if jsonFormat:
4007 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004008 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004009 assert "Command not found:" not in output, output
4010 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004011 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004012 return output
Jon Hall390696c2015-05-05 17:13:41 -07004013 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004014 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004015 return None
Jon Hall390696c2015-05-05 17:13:41 -07004016 except TypeError:
4017 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004018 return None
Jon Hall390696c2015-05-05 17:13:41 -07004019 except pexpect.EOF:
4020 main.log.error( self.name + ": EOF exception found" )
4021 main.log.error( self.name + ": " + self.handle.before )
4022 main.cleanup()
4023 main.exit()
4024 except Exception:
4025 main.log.exception( self.name + ": Uncaught exception!" )
4026 main.cleanup()
4027 main.exit()
4028
Jon Hall935db192016-04-19 00:22:04 -07004029 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004030 """
Jon Halle1a3b752015-07-22 13:02:46 -07004031 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004032 Required arguments:
4033 counter - The name of the counter to increment.
4034 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004035 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004036 returns:
4037 integer value of the counter or
4038 None on Error
4039 """
4040 try:
4041 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004042 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004043 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004044 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004045 if delta != 1:
4046 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004047 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004048 try:
4049 # TODO: Maybe make this less hardcoded
4050 # ConsistentMap Exceptions
4051 assert "org.onosproject.store.service" not in output
4052 # Node not leader
4053 assert "java.lang.IllegalStateException" not in output
4054 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004055 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004056 "command: " + str( output ) )
4057 retryTime = 30 # Conservative time, given by Madan
4058 main.log.info( "Waiting " + str( retryTime ) +
4059 "seconds before retrying." )
4060 time.sleep( retryTime ) # Due to change in mastership
4061 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004062 assert "Command not found:" not in output, output
4063 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004064 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004065 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004066 match = re.search( pattern, output )
4067 if match:
4068 return int( match.group( 1 ) )
4069 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004070 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004071 " match expected output." )
4072 main.log.debug( self.name + " expected: " + pattern )
4073 main.log.debug( self.name + " actual: " + repr( output ) )
4074 return None
4075 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004076 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004077 return None
4078 except TypeError:
4079 main.log.exception( self.name + ": Object not as expected" )
4080 return None
4081 except pexpect.EOF:
4082 main.log.error( self.name + ": EOF exception found" )
4083 main.log.error( self.name + ": " + self.handle.before )
4084 main.cleanup()
4085 main.exit()
4086 except Exception:
4087 main.log.exception( self.name + ": Uncaught exception!" )
4088 main.cleanup()
4089 main.exit()
4090
Jon Hall935db192016-04-19 00:22:04 -07004091 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004092 """
4093 CLI command to get a distributed counter then add a delta to it.
4094 Required arguments:
4095 counter - The name of the counter to increment.
4096 Optional arguments:
4097 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004098 returns:
4099 integer value of the counter or
4100 None on Error
4101 """
4102 try:
4103 counter = str( counter )
4104 delta = int( delta )
4105 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004106 cmdStr += counter
4107 if delta != 1:
4108 cmdStr += " " + str( delta )
4109 output = self.sendline( cmdStr )
4110 try:
4111 # TODO: Maybe make this less hardcoded
4112 # ConsistentMap Exceptions
4113 assert "org.onosproject.store.service" not in output
4114 # Node not leader
4115 assert "java.lang.IllegalStateException" not in output
4116 except AssertionError:
4117 main.log.error( "Error in processing '" + cmdStr + "' " +
4118 "command: " + str( output ) )
4119 retryTime = 30 # Conservative time, given by Madan
4120 main.log.info( "Waiting " + str( retryTime ) +
4121 "seconds before retrying." )
4122 time.sleep( retryTime ) # Due to change in mastership
4123 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004124 assert "Command not found:" not in output, output
4125 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004126 main.log.info( self.name + ": " + output )
4127 pattern = counter + " was updated to (-?\d+)"
4128 match = re.search( pattern, output )
4129 if match:
4130 return int( match.group( 1 ) )
4131 else:
4132 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4133 " match expected output." )
4134 main.log.debug( self.name + " expected: " + pattern )
4135 main.log.debug( self.name + " actual: " + repr( output ) )
4136 return None
4137 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004138 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004139 return None
4140 except TypeError:
4141 main.log.exception( self.name + ": Object not as expected" )
4142 return None
4143 except pexpect.EOF:
4144 main.log.error( self.name + ": EOF exception found" )
4145 main.log.error( self.name + ": " + self.handle.before )
4146 main.cleanup()
4147 main.exit()
4148 except Exception:
4149 main.log.exception( self.name + ": Uncaught exception!" )
4150 main.cleanup()
4151 main.exit()
4152
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004153 def summary( self, jsonFormat=True ):
4154 """
4155 Description: Execute summary command in onos
4156 Returns: json object ( summary -j ), returns main.FALSE if there is
4157 no output
4158
4159 """
4160 try:
4161 cmdStr = "summary"
4162 if jsonFormat:
4163 cmdStr += " -j"
4164 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004165 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004166 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004167 if not handle:
4168 main.log.error( self.name + ": There is no output in " +
4169 "summary command" )
4170 return main.FALSE
4171 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004172 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004173 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004174 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004175 except TypeError:
4176 main.log.exception( self.name + ": Object not as expected" )
4177 return None
4178 except pexpect.EOF:
4179 main.log.error( self.name + ": EOF exception found" )
4180 main.log.error( self.name + ": " + self.handle.before )
4181 main.cleanup()
4182 main.exit()
4183 except Exception:
4184 main.log.exception( self.name + ": Uncaught exception!" )
4185 main.cleanup()
4186 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004187
Jon Hall935db192016-04-19 00:22:04 -07004188 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004189 """
4190 CLI command to get the value of a key in a consistent map using
4191 transactions. This a test function and can only get keys from the
4192 test map hard coded into the cli command
4193 Required arguments:
4194 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004195 returns:
4196 The string value of the key or
4197 None on Error
4198 """
4199 try:
4200 keyName = str( keyName )
4201 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004202 cmdStr += keyName
4203 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004204 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004205 try:
4206 # TODO: Maybe make this less hardcoded
4207 # ConsistentMap Exceptions
4208 assert "org.onosproject.store.service" not in output
4209 # Node not leader
4210 assert "java.lang.IllegalStateException" not in output
4211 except AssertionError:
4212 main.log.error( "Error in processing '" + cmdStr + "' " +
4213 "command: " + str( output ) )
4214 return None
4215 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4216 if "Key " + keyName + " not found." in output:
4217 return None
4218 else:
4219 match = re.search( pattern, output )
4220 if match:
4221 return match.groupdict()[ 'value' ]
4222 else:
4223 main.log.error( self.name + ": transactionlMapGet did not" +
4224 " match expected output." )
4225 main.log.debug( self.name + " expected: " + pattern )
4226 main.log.debug( self.name + " actual: " + repr( output ) )
4227 return None
Jon Hallc6793552016-01-19 14:18:37 -08004228 except AssertionError:
4229 main.log.exception( "" )
4230 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004231 except TypeError:
4232 main.log.exception( self.name + ": Object not as expected" )
4233 return None
4234 except pexpect.EOF:
4235 main.log.error( self.name + ": EOF exception found" )
4236 main.log.error( self.name + ": " + self.handle.before )
4237 main.cleanup()
4238 main.exit()
4239 except Exception:
4240 main.log.exception( self.name + ": Uncaught exception!" )
4241 main.cleanup()
4242 main.exit()
4243
Jon Hall935db192016-04-19 00:22:04 -07004244 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004245 """
4246 CLI command to put a value into 'numKeys' number of keys in a
4247 consistent map using transactions. This a test function and can only
4248 put into keys named 'Key#' of the test map hard coded into the cli command
4249 Required arguments:
4250 numKeys - Number of keys to add the value to
4251 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004252 returns:
4253 A dictionary whose keys are the name of the keys put into the map
4254 and the values of the keys are dictionaries whose key-values are
4255 'value': value put into map and optionaly
4256 'oldValue': Previous value in the key or
4257 None on Error
4258
4259 Example output
4260 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4261 'Key2': {'value': 'Testing'} }
4262 """
4263 try:
4264 numKeys = str( numKeys )
4265 value = str( value )
4266 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004267 cmdStr += numKeys + " " + value
4268 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004269 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004270 try:
4271 # TODO: Maybe make this less hardcoded
4272 # ConsistentMap Exceptions
4273 assert "org.onosproject.store.service" not in output
4274 # Node not leader
4275 assert "java.lang.IllegalStateException" not in output
4276 except AssertionError:
4277 main.log.error( "Error in processing '" + cmdStr + "' " +
4278 "command: " + str( output ) )
4279 return None
4280 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4281 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4282 results = {}
4283 for line in output.splitlines():
4284 new = re.search( newPattern, line )
4285 updated = re.search( updatedPattern, line )
4286 if new:
4287 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4288 elif updated:
4289 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004290 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004291 else:
4292 main.log.error( self.name + ": transactionlMapGet did not" +
4293 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004294 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4295 newPattern,
4296 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004297 main.log.debug( self.name + " actual: " + repr( output ) )
4298 return results
Jon Hallc6793552016-01-19 14:18:37 -08004299 except AssertionError:
4300 main.log.exception( "" )
4301 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004302 except TypeError:
4303 main.log.exception( self.name + ": Object not as expected" )
4304 return None
4305 except pexpect.EOF:
4306 main.log.error( self.name + ": EOF exception found" )
4307 main.log.error( self.name + ": " + self.handle.before )
4308 main.cleanup()
4309 main.exit()
4310 except Exception:
4311 main.log.exception( self.name + ": Uncaught exception!" )
4312 main.cleanup()
4313 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004314
acsmarsdaea66c2015-09-03 11:44:06 -07004315 def maps( self, jsonFormat=True ):
4316 """
4317 Description: Returns result of onos:maps
4318 Optional:
4319 * jsonFormat: enable json formatting of output
4320 """
4321 try:
4322 cmdStr = "maps"
4323 if jsonFormat:
4324 cmdStr += " -j"
4325 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004326 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004327 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004328 except AssertionError:
4329 main.log.exception( "" )
4330 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004331 except TypeError:
4332 main.log.exception( self.name + ": Object not as expected" )
4333 return None
4334 except pexpect.EOF:
4335 main.log.error( self.name + ": EOF exception found" )
4336 main.log.error( self.name + ": " + self.handle.before )
4337 main.cleanup()
4338 main.exit()
4339 except Exception:
4340 main.log.exception( self.name + ": Uncaught exception!" )
4341 main.cleanup()
4342 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004343
4344 def getSwController( self, uri, jsonFormat=True ):
4345 """
4346 Descrition: Gets the controller information from the device
4347 """
4348 try:
4349 cmd = "device-controllers "
4350 if jsonFormat:
4351 cmd += "-j "
4352 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004353 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004354 return response
Jon Hallc6793552016-01-19 14:18:37 -08004355 except AssertionError:
4356 main.log.exception( "" )
4357 return None
GlennRC050596c2015-11-18 17:06:41 -08004358 except TypeError:
4359 main.log.exception( self.name + ": Object not as expected" )
4360 return None
4361 except pexpect.EOF:
4362 main.log.error( self.name + ": EOF exception found" )
4363 main.log.error( self.name + ": " + self.handle.before )
4364 main.cleanup()
4365 main.exit()
4366 except Exception:
4367 main.log.exception( self.name + ": Uncaught exception!" )
4368 main.cleanup()
4369 main.exit()
4370
4371 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4372 """
4373 Descrition: sets the controller(s) for the specified device
4374
4375 Parameters:
4376 Required: uri - String: The uri of the device(switch).
4377 ip - String or List: The ip address of the controller.
4378 This parameter can be formed in a couple of different ways.
4379 VALID:
4380 10.0.0.1 - just the ip address
4381 tcp:10.0.0.1 - the protocol and the ip address
4382 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4383 so that you can add controllers with different
4384 protocols and ports
4385 INVALID:
4386 10.0.0.1:6653 - this is not supported by ONOS
4387
4388 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4389 port - The port number.
4390 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4391
4392 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4393 """
4394 try:
4395 cmd = "device-setcontrollers"
4396
4397 if jsonFormat:
4398 cmd += " -j"
4399 cmd += " " + uri
4400 if isinstance( ip, str ):
4401 ip = [ip]
4402 for item in ip:
4403 if ":" in item:
4404 sitem = item.split( ":" )
4405 if len(sitem) == 3:
4406 cmd += " " + item
4407 elif "." in sitem[1]:
4408 cmd += " {}:{}".format(item, port)
4409 else:
4410 main.log.error( "Malformed entry: " + item )
4411 raise TypeError
4412 else:
4413 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004414 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004415 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004416 if "Error" in response:
4417 main.log.error( response )
4418 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004419 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004420 except AssertionError:
4421 main.log.exception( "" )
4422 return None
GlennRC050596c2015-11-18 17:06:41 -08004423 except TypeError:
4424 main.log.exception( self.name + ": Object not as expected" )
4425 return main.FALSE
4426 except pexpect.EOF:
4427 main.log.error( self.name + ": EOF exception found" )
4428 main.log.error( self.name + ": " + self.handle.before )
4429 main.cleanup()
4430 main.exit()
4431 except Exception:
4432 main.log.exception( self.name + ": Uncaught exception!" )
4433 main.cleanup()
4434 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004435
4436 def removeDevice( self, device ):
4437 '''
4438 Description:
4439 Remove a device from ONOS by passing the uri of the device(s).
4440 Parameters:
4441 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4442 Returns:
4443 Returns main.FALSE if an exception is thrown or an error is present
4444 in the response. Otherwise, returns main.TRUE.
4445 NOTE:
4446 If a host cannot be removed, then this function will return main.FALSE
4447 '''
4448 try:
4449 if type( device ) is str:
4450 device = list( device )
4451
4452 for d in device:
4453 time.sleep( 1 )
4454 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004455 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004456 if "Error" in response:
4457 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4458 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004459 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004460 except AssertionError:
4461 main.log.exception( "" )
4462 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -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
4476 def removeHost( self, host ):
4477 '''
4478 Description:
4479 Remove a host from ONOS by passing the id of the host(s)
4480 Parameters:
4481 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4482 Returns:
4483 Returns main.FALSE if an exception is thrown or an error is present
4484 in the response. Otherwise, returns main.TRUE.
4485 NOTE:
4486 If a host cannot be removed, then this function will return main.FALSE
4487 '''
4488 try:
4489 if type( host ) is str:
4490 host = list( host )
4491
4492 for h in host:
4493 time.sleep( 1 )
4494 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004495 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004496 if "Error" in response:
4497 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4498 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004499 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004500 except AssertionError:
4501 main.log.exception( "" )
4502 return None
GlennRC20fc6522015-12-23 23:26:57 -08004503 except TypeError:
4504 main.log.exception( self.name + ": Object not as expected" )
4505 return main.FALSE
4506 except pexpect.EOF:
4507 main.log.error( self.name + ": EOF exception found" )
4508 main.log.error( self.name + ": " + self.handle.before )
4509 main.cleanup()
4510 main.exit()
4511 except Exception:
4512 main.log.exception( self.name + ": Uncaught exception!" )
4513 main.cleanup()
4514 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004515
Jon Hallc6793552016-01-19 14:18:37 -08004516 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004517 '''
4518 Description:
4519 Bring link down or up in the null-provider.
4520 params:
4521 begin - (string) One end of a device or switch.
4522 end - (string) the other end of the device or switch
4523 returns:
4524 main.TRUE if no exceptions were thrown and no Errors are
4525 present in the resoponse. Otherwise, returns main.FALSE
4526 '''
4527 try:
Jon Hallc6793552016-01-19 14:18:37 -08004528 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004529 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004530 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004531 if "Error" in response or "Failure" in response:
4532 main.log.error( response )
4533 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004534 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004535 except AssertionError:
4536 main.log.exception( "" )
4537 return None
GlennRCed771242016-01-13 17:02:47 -08004538 except TypeError:
4539 main.log.exception( self.name + ": Object not as expected" )
4540 return main.FALSE
4541 except pexpect.EOF:
4542 main.log.error( self.name + ": EOF exception found" )
4543 main.log.error( self.name + ": " + self.handle.before )
4544 main.cleanup()
4545 main.exit()
4546 except Exception:
4547 main.log.exception( self.name + ": Uncaught exception!" )
4548 main.cleanup()
4549 main.exit()
4550