blob: c7ae79beaf8dc86a8c0fc71e7263a0119793d08a [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
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002142 def checkFlowCount(self, min=0, timeout=60 ):
2143 count = int(self.getTotalFlowsNum( timeout=timeout ))
2144 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002145
Jon Hallc6793552016-01-19 14:18:37 -08002146 def checkFlowsState( self, isPENDING=True, timeout=60 ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002147 """
2148 Description:
GlennRCed771242016-01-13 17:02:47 -08002149 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002150 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2151 if the count of those states is 0, which means all current flows
2152 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002153 Optional:
GlennRCed771242016-01-13 17:02:47 -08002154 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002155 Return:
2156 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002157 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002158 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002159 """
2160 try:
GlennRCed771242016-01-13 17:02:47 -08002161 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2162 checkedStates = []
2163 statesCount = [0, 0, 0, 0]
2164 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002165 rawFlows = self.flows( state=s, timeout = timeout )
2166 checkedStates.append( json.loads( rawFlows ) )
2167 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002168 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002169 try:
2170 statesCount[i] += int( c.get( "flowCount" ) )
2171 except TypeError:
2172 main.log.exception( "Json object not as expected" )
2173 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002174
GlennRCed771242016-01-13 17:02:47 -08002175 # We want to count PENDING_ADD if isPENDING is true
2176 if isPENDING:
2177 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2178 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002179 else:
GlennRCed771242016-01-13 17:02:47 -08002180 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2181 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002182 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002183 except ( TypeError, ValueError ):
2184 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002185 return None
2186 except pexpect.EOF:
2187 main.log.error( self.name + ": EOF exception found" )
2188 main.log.error( self.name + ": " + self.handle.before )
2189 main.cleanup()
2190 main.exit()
2191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
2193 main.cleanup()
2194 main.exit()
2195
GlennRCed771242016-01-13 17:02:47 -08002196 def pushTestIntents( self, ingress, egress, batchSize, offset="",
2197 options="", timeout=10, background = False ):
kelvin8ec71442015-01-15 16:57:00 -08002198 """
andrewonlab87852b02014-11-19 18:44:19 -05002199 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002200 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002201 a specific point-to-point intent definition
2202 Required:
GlennRCed771242016-01-13 17:02:47 -08002203 * ingress: specify source dpid
2204 * egress: specify destination dpid
2205 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002206 Optional:
GlennRCed771242016-01-13 17:02:47 -08002207 * offset: the keyOffset is where the next batch of intents
2208 will be installed
2209 Returns: If failed to push test intents, it will returen None,
2210 if successful, return true.
2211 Timeout expection will return None,
2212 TypeError will return false
2213 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002214 """
andrewonlab87852b02014-11-19 18:44:19 -05002215 try:
GlennRCed771242016-01-13 17:02:47 -08002216 if background:
2217 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002218 else:
GlennRCed771242016-01-13 17:02:47 -08002219 back = ""
2220 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002221 ingress,
2222 egress,
2223 batchSize,
2224 offset,
2225 back )
GlennRCed771242016-01-13 17:02:47 -08002226 response = self.sendline( cmd, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -08002227 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002228 main.log.info( response )
2229 if response == None:
2230 return None
2231
2232 # TODO: We should handle if there is failure in installation
2233 return main.TRUE
2234
Jon Hallc6793552016-01-19 14:18:37 -08002235 except AssertionError:
2236 main.log.exception( "" )
2237 return None
GlennRCed771242016-01-13 17:02:47 -08002238 except pexpect.TIMEOUT:
2239 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002240 return None
andrewonlab87852b02014-11-19 18:44:19 -05002241 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002242 main.log.error( self.name + ": EOF exception found" )
2243 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002244 main.cleanup()
2245 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002246 except TypeError:
2247 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002248 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002249 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002250 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002251 main.cleanup()
2252 main.exit()
2253
YPZhangf6f14a02016-01-28 15:17:31 -08002254 def getTotalFlowsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002255 """
2256 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002257 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002258 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002259 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002260 """
YPZhange3109a72016-02-02 11:25:37 -08002261
YPZhangb5d3f832016-01-23 22:54:26 -08002262 try:
YPZhange3109a72016-02-02 11:25:37 -08002263 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002264 cmd = "flows -s|grep ADDED|wc -l"
YPZhange3109a72016-02-02 11:25:37 -08002265 totalFlows = self.sendline( cmd, timeout=timeout )
2266
2267 if totalFlows == None:
2268 # if timeout, we will get total number of all flows, and subtract other states
2269 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2270 checkedStates = []
2271 totalFlows = 0
2272 statesCount = [0, 0, 0, 0]
2273
2274 # get total flows from summary
2275 response = json.loads( self.sendline( "summary -j", timeout=timeout ) )
2276 totalFlows = int( response.get("flows") )
2277
2278 for s in states:
2279 rawFlows = self.flows( state=s, timeout = timeout )
2280 if rawFlows == None:
2281 # if timeout, return the total flows number from summary command
2282 return totalFlows
2283 checkedStates.append( json.loads( rawFlows ) )
2284
2285 # Calculate ADDED flows number, equal total subtracts others
2286 for i in range( len( states ) ):
2287 for c in checkedStates[i]:
2288 try:
2289 statesCount[i] += int( c.get( "flowCount" ) )
2290 except TypeError:
2291 main.log.exception( "Json object not as expected" )
2292 totalFlows = totalFlows - int( statesCount[i] )
2293 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2294
2295 return totalFlows
2296
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002297 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002298
YPZhangb5d3f832016-01-23 22:54:26 -08002299 except TypeError:
2300 main.log.exception( self.name + ": Object not as expected" )
2301 return None
2302 except pexpect.EOF:
2303 main.log.error( self.name + ": EOF exception found" )
2304 main.log.error( self.name + ": " + self.handle.before )
2305 main.cleanup()
2306 main.exit()
2307 except Exception:
2308 main.log.exception( self.name + ": Uncaught exception!" )
2309 main.cleanup()
2310 main.exit()
2311
2312 def getTotalIntentsNum( self ):
2313 """
2314 Description:
2315 Get the total number of intents, include every states.
2316 Return:
2317 The number of intents
2318 """
2319 try:
2320 cmd = "summary -j"
2321 response = self.sendline( cmd )
2322 if response == None:
2323 return -1
2324 response = json.loads( response )
2325 return int( response.get("intents") )
2326 except TypeError:
2327 main.log.exception( self.name + ": Object not as expected" )
2328 return None
2329 except pexpect.EOF:
2330 main.log.error( self.name + ": EOF exception found" )
2331 main.log.error( self.name + ": " + self.handle.before )
2332 main.cleanup()
2333 main.exit()
2334 except Exception:
2335 main.log.exception( self.name + ": Uncaught exception!" )
2336 main.cleanup()
2337 main.exit()
2338
kelvin-onlabd3b64892015-01-20 13:26:24 -08002339 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002340 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002341 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002342 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002343 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002344 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002345 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002346 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002347 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002348 cmdStr += " -j"
2349 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002350 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002351 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002352 except AssertionError:
2353 main.log.exception( "" )
2354 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002355 except TypeError:
2356 main.log.exception( self.name + ": Object not as expected" )
2357 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002358 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002359 main.log.error( self.name + ": EOF exception found" )
2360 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002361 main.cleanup()
2362 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002363 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002364 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002365 main.cleanup()
2366 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002367
kelvin-onlabd3b64892015-01-20 13:26:24 -08002368 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002369 """
2370 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002371 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002372 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002373 """
andrewonlab867212a2014-10-22 20:13:38 -04002374 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002375 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002376 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002377 cmdStr += " -j"
2378 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002379 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002380 if handle:
2381 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002382 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002383 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002384 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002385 else:
2386 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002387 except AssertionError:
2388 main.log.exception( "" )
2389 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002390 except TypeError:
2391 main.log.exception( self.name + ": Object not as expected" )
2392 return None
andrewonlab867212a2014-10-22 20:13:38 -04002393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002394 main.log.error( self.name + ": EOF exception found" )
2395 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002396 main.cleanup()
2397 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002398 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002399 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002400 main.cleanup()
2401 main.exit()
2402
kelvin8ec71442015-01-15 16:57:00 -08002403 # Wrapper functions ****************
2404 # Wrapper functions use existing driver
2405 # functions and extends their use case.
2406 # For example, we may use the output of
2407 # a normal driver function, and parse it
2408 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002409
kelvin-onlabd3b64892015-01-20 13:26:24 -08002410 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002411 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002412 Description:
2413 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002414 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002415 try:
kelvin8ec71442015-01-15 16:57:00 -08002416 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002417 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002418 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002419
kelvin8ec71442015-01-15 16:57:00 -08002420 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002421 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2422 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002423 match = re.search('id=0x([\da-f]+),', intents)
2424 if match:
2425 tmpId = match.group()[3:-1]
2426 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002427 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002428
Jon Halld4d4b372015-01-28 16:02:41 -08002429 except TypeError:
2430 main.log.exception( self.name + ": Object not as expected" )
2431 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002432 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002433 main.log.error( self.name + ": EOF exception found" )
2434 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002435 main.cleanup()
2436 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002437 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002438 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002439 main.cleanup()
2440 main.exit()
2441
Jon Hall30b82fa2015-03-04 17:15:43 -08002442 def FlowAddedCount( self, deviceId ):
2443 """
2444 Determine the number of flow rules for the given device id that are
2445 in the added state
2446 """
2447 try:
2448 cmdStr = "flows any " + str( deviceId ) + " | " +\
2449 "grep 'state=ADDED' | wc -l"
2450 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002451 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002452 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002453 except AssertionError:
2454 main.log.exception( "" )
2455 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002456 except pexpect.EOF:
2457 main.log.error( self.name + ": EOF exception found" )
2458 main.log.error( self.name + ": " + self.handle.before )
2459 main.cleanup()
2460 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002461 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002462 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002463 main.cleanup()
2464 main.exit()
2465
kelvin-onlabd3b64892015-01-20 13:26:24 -08002466 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002467 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002468 Use 'devices' function to obtain list of all devices
2469 and parse the result to obtain a list of all device
2470 id's. Returns this list. Returns empty list if no
2471 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002472 List is ordered sequentially
2473
andrewonlab3e15ead2014-10-15 14:21:34 -04002474 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002475 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002476 the ids. By obtaining the list of device ids on the fly,
2477 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002478 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002479 try:
kelvin8ec71442015-01-15 16:57:00 -08002480 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002481 devicesStr = self.devices( jsonFormat=False )
2482 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002483
kelvin-onlabd3b64892015-01-20 13:26:24 -08002484 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002485 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002486 return idList
kelvin8ec71442015-01-15 16:57:00 -08002487
2488 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002489 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002490 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002491 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002492 # Split list further into arguments before and after string
2493 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002494 # append to idList
2495 for arg in tempList:
2496 idList.append( arg.split( "id=" )[ 1 ] )
2497 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002498
Jon Halld4d4b372015-01-28 16:02:41 -08002499 except TypeError:
2500 main.log.exception( self.name + ": Object not as expected" )
2501 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002502 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002505 main.cleanup()
2506 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002507 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002508 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002509 main.cleanup()
2510 main.exit()
2511
kelvin-onlabd3b64892015-01-20 13:26:24 -08002512 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002513 """
andrewonlab7c211572014-10-15 16:45:20 -04002514 Uses 'nodes' function to obtain list of all nodes
2515 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002516 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002517 Returns:
2518 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002519 """
andrewonlab7c211572014-10-15 16:45:20 -04002520 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002521 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002522 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002523 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002524 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002525 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002526 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002527 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002528 nodesJson = json.loads( nodesStr )
2529 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002530 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002531 except ( TypeError, ValueError ):
2532 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002533 return None
andrewonlab7c211572014-10-15 16:45:20 -04002534 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002535 main.log.error( self.name + ": EOF exception found" )
2536 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002537 main.cleanup()
2538 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002540 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002541 main.cleanup()
2542 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002543
kelvin-onlabd3b64892015-01-20 13:26:24 -08002544 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002545 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002546 Return the first device from the devices api whose 'id' contains 'dpid'
2547 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002548 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002549 try:
kelvin8ec71442015-01-15 16:57:00 -08002550 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002551 return None
2552 else:
kelvin8ec71442015-01-15 16:57:00 -08002553 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002554 rawDevices = self.devices()
2555 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002556 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002557 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002558 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2559 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002560 return device
2561 return None
Jon Hallc6793552016-01-19 14:18:37 -08002562 except ( TypeError, ValueError ):
2563 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002564 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002565 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002566 main.log.error( self.name + ": EOF exception found" )
2567 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002568 main.cleanup()
2569 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002570 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002571 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002572 main.cleanup()
2573 main.exit()
2574
You Wang24139872016-05-03 11:48:47 -07002575 def getTopology( self, topologyOutput ):
2576 """
2577 Definition:
2578 Loads a json topology output
2579 Return:
2580 topology = current ONOS topology
2581 """
2582 import json
2583 try:
2584 # either onos:topology or 'topology' will work in CLI
2585 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002586 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002587 return topology
2588 except pexpect.EOF:
2589 main.log.error( self.name + ": EOF exception found" )
2590 main.log.error( self.name + ": " + self.handle.before )
2591 main.cleanup()
2592 main.exit()
2593 except Exception:
2594 main.log.exception( self.name + ": Uncaught exception!" )
2595 main.cleanup()
2596 main.exit()
2597
2598 def checkStatus(
2599 self,
2600 topologyResult,
2601 numoswitch,
2602 numolink,
2603 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002604 """
Jon Hallefbd9792015-03-05 16:11:36 -08002605 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002606 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002607 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002608
You Wang24139872016-05-03 11:48:47 -07002609 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002610 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002611 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002612 logLevel = level to log to.
2613 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002614
Jon Hallefbd9792015-03-05 16:11:36 -08002615 Returns: main.TRUE if the number of switches and links are correct,
2616 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002617 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002618 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002619 try:
You Wang24139872016-05-03 11:48:47 -07002620 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002621 if topology == {}:
2622 return main.ERROR
2623 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002624 # Is the number of switches is what we expected
2625 devices = topology.get( 'devices', False )
2626 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002627 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002628 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002629 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002630 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002631 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002632 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002633 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002634 output = output + "The number of links and switches match "\
2635 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002636 result = main.TRUE
2637 else:
You Wang24139872016-05-03 11:48:47 -07002638 output = output + \
2639 "The number of links and switches does not match " + \
2640 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002641 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002642 output = output + "\n ONOS sees %i devices" % int( devices )
2643 output = output + " (%i expected) " % int( numoswitch )
2644 output = output + "and %i links " % int( links )
2645 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002647 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002649 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002650 else:
You Wang24139872016-05-03 11:48:47 -07002651 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002652 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002653 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002654 main.log.error( self.name + ": EOF exception found" )
2655 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002656 main.cleanup()
2657 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002658 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002659 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002660 main.cleanup()
2661 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002662
kelvin-onlabd3b64892015-01-20 13:26:24 -08002663 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002664 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002665 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002666 deviceId must be the id of a device as seen in the onos devices command
2667 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002668 role must be either master, standby, or none
2669
Jon Halle3f39ff2015-01-13 11:50:53 -08002670 Returns:
2671 main.TRUE or main.FALSE based on argument verification and
2672 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002673 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002674 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002675 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002676 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002677 cmdStr = "device-role " +\
2678 str( deviceId ) + " " +\
2679 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002680 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002681 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002682 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002683 if re.search( "Error", handle ):
2684 # end color output to escape any colours
2685 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002686 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002687 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002688 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002689 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002690 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002691 main.log.error( "Invalid 'role' given to device_role(). " +
2692 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002693 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002694 except AssertionError:
2695 main.log.exception( "" )
2696 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002697 except TypeError:
2698 main.log.exception( self.name + ": Object not as expected" )
2699 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002703 main.cleanup()
2704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002706 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002707 main.cleanup()
2708 main.exit()
2709
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002711 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002712 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002713 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002714 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002715 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002716 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002717 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002718 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002719 cmdStr += " -j"
2720 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002721 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002722 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002723 except AssertionError:
2724 main.log.exception( "" )
2725 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002726 except TypeError:
2727 main.log.exception( self.name + ": Object not as expected" )
2728 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002729 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002730 main.log.error( self.name + ": EOF exception found" )
2731 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002732 main.cleanup()
2733 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002735 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002736 main.cleanup()
2737 main.exit()
2738
kelvin-onlabd3b64892015-01-20 13:26:24 -08002739 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002740 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002741 CLI command to get the current leader for the Election test application
2742 NOTE: Requires installation of the onos-app-election feature
2743 Returns: Node IP of the leader if one exists
2744 None if none exists
2745 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002746 """
Jon Hall94fd0472014-12-08 11:52:42 -08002747 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002748 cmdStr = "election-test-leader"
2749 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002750 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002751 # Leader
2752 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002753 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 nodeSearch = re.search( leaderPattern, response )
2755 if nodeSearch:
2756 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002757 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002758 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002759 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002760 # no leader
2761 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002762 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002763 nullSearch = re.search( nullPattern, response )
2764 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002765 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002766 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002767 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002768 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002769 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002770 if re.search( errorPattern, response ):
2771 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002772 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002773 return main.FALSE
2774 else:
Jon Hall390696c2015-05-05 17:13:41 -07002775 main.log.error( "Error in electionTestLeader on " + self.name +
2776 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002777 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002778 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002779 except AssertionError:
2780 main.log.exception( "" )
2781 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002782 except TypeError:
2783 main.log.exception( self.name + ": Object not as expected" )
2784 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002785 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002786 main.log.error( self.name + ": EOF exception found" )
2787 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002788 main.cleanup()
2789 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002790 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002791 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002792 main.cleanup()
2793 main.exit()
2794
kelvin-onlabd3b64892015-01-20 13:26:24 -08002795 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002796 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002797 CLI command to run for leadership of the Election test application.
2798 NOTE: Requires installation of the onos-app-election feature
2799 Returns: Main.TRUE on success
2800 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002801 """
Jon Hall94fd0472014-12-08 11:52:42 -08002802 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002803 cmdStr = "election-test-run"
2804 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002805 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002806 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002807 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002808 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002809 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002810 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002811 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002812 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002813 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002814 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002815 errorPattern = "Command\snot\sfound"
2816 if re.search( errorPattern, response ):
2817 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002818 return main.FALSE
2819 else:
Jon Hall390696c2015-05-05 17:13:41 -07002820 main.log.error( "Error in electionTestRun on " + self.name +
2821 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002822 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002823 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002824 except AssertionError:
2825 main.log.exception( "" )
2826 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002827 except TypeError:
2828 main.log.exception( self.name + ": Object not as expected" )
2829 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002830 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002831 main.log.error( self.name + ": EOF exception found" )
2832 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002833 main.cleanup()
2834 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002835 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002836 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002837 main.cleanup()
2838 main.exit()
2839
kelvin-onlabd3b64892015-01-20 13:26:24 -08002840 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002841 """
Jon Hall94fd0472014-12-08 11:52:42 -08002842 * CLI command to withdraw the local node from leadership election for
2843 * the Election test application.
2844 #NOTE: Requires installation of the onos-app-election feature
2845 Returns: Main.TRUE on success
2846 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002847 """
Jon Hall94fd0472014-12-08 11:52:42 -08002848 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 cmdStr = "election-test-withdraw"
2850 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002851 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002852 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002853 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002854 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002855 if re.search( successPattern, response ):
2856 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002857 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002858 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002859 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002860 errorPattern = "Command\snot\sfound"
2861 if re.search( errorPattern, response ):
2862 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002863 return main.FALSE
2864 else:
Jon Hall390696c2015-05-05 17:13:41 -07002865 main.log.error( "Error in electionTestWithdraw on " +
2866 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002867 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002868 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002869 except AssertionError:
2870 main.log.exception( "" )
2871 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002872 except TypeError:
2873 main.log.exception( self.name + ": Object not as expected" )
2874 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002875 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002876 main.log.error( self.name + ": EOF exception found" )
2877 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002878 main.cleanup()
2879 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002880 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002881 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002882 main.cleanup()
2883 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002884
kelvin8ec71442015-01-15 16:57:00 -08002885 def getDevicePortsEnabledCount( self, dpid ):
2886 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002887 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002888 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002889 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002890 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002891 cmdStr = "onos:ports -e " + dpid + " | wc -l"
2892 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002893 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002894 if re.search( "No such device", output ):
2895 main.log.error( "Error in getting ports" )
2896 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002897 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002898 return output
Jon Hallc6793552016-01-19 14:18:37 -08002899 except AssertionError:
2900 main.log.exception( "" )
2901 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002902 except TypeError:
2903 main.log.exception( self.name + ": Object not as expected" )
2904 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002906 main.log.error( self.name + ": EOF exception found" )
2907 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002908 main.cleanup()
2909 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002910 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002911 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002912 main.cleanup()
2913 main.exit()
2914
kelvin8ec71442015-01-15 16:57:00 -08002915 def getDeviceLinksActiveCount( self, dpid ):
2916 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002917 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08002918 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002919 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002920 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
2922 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002923 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002924 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002925 main.log.error( "Error in getting ports " )
2926 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002927 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002928 return output
Jon Hallc6793552016-01-19 14:18:37 -08002929 except AssertionError:
2930 main.log.exception( "" )
2931 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002932 except TypeError:
2933 main.log.exception( self.name + ": Object not as expected" )
2934 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002935 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002936 main.log.error( self.name + ": EOF exception found" )
2937 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002938 main.cleanup()
2939 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002940 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002941 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002942 main.cleanup()
2943 main.exit()
2944
kelvin8ec71442015-01-15 16:57:00 -08002945 def getAllIntentIds( self ):
2946 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002947 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08002948 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002949 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002950 cmdStr = "onos:intents | grep id="
2951 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002952 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08002953 if re.search( "Error", output ):
2954 main.log.error( "Error in getting ports" )
2955 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002956 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002957 return output
Jon Hallc6793552016-01-19 14:18:37 -08002958 except AssertionError:
2959 main.log.exception( "" )
2960 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002961 except TypeError:
2962 main.log.exception( self.name + ": Object not as expected" )
2963 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002964 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002965 main.log.error( self.name + ": EOF exception found" )
2966 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08002967 main.cleanup()
2968 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002969 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002970 main.log.exception( self.name + ": Uncaught exception!" )
2971 main.cleanup()
2972 main.exit()
2973
Jon Hall73509952015-02-24 16:42:56 -08002974 def intentSummary( self ):
2975 """
Jon Hallefbd9792015-03-05 16:11:36 -08002976 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08002977 """
2978 try:
2979 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07002980 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002981 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07002982 states.append( intent.get( 'state', None ) )
2983 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08002984 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08002985 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08002986 except ( TypeError, ValueError ):
2987 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08002988 return None
2989 except pexpect.EOF:
2990 main.log.error( self.name + ": EOF exception found" )
2991 main.log.error( self.name + ": " + self.handle.before )
2992 main.cleanup()
2993 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002994 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08002995 main.log.exception( self.name + ": Uncaught exception!" )
2996 main.cleanup()
2997 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08002998
Jon Hall61282e32015-03-19 11:34:11 -07002999 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003000 """
3001 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003002 Optional argument:
3003 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003004 """
Jon Hall63604932015-02-26 17:09:50 -08003005 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003006 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003007 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003008 cmdStr += " -j"
3009 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003010 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003011 return output
Jon Hallc6793552016-01-19 14:18:37 -08003012 except AssertionError:
3013 main.log.exception( "" )
3014 return None
Jon Hall63604932015-02-26 17:09:50 -08003015 except TypeError:
3016 main.log.exception( self.name + ": Object not as expected" )
3017 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003018 except pexpect.EOF:
3019 main.log.error( self.name + ": EOF exception found" )
3020 main.log.error( self.name + ": " + self.handle.before )
3021 main.cleanup()
3022 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003023 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003024 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003025 main.cleanup()
3026 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003027
acsmarsa4a4d1e2015-07-10 16:01:24 -07003028 def leaderCandidates( self, jsonFormat=True ):
3029 """
3030 Returns the output of the leaders -c command.
3031 Optional argument:
3032 * jsonFormat - boolean indicating if you want output in json
3033 """
3034 try:
3035 cmdStr = "onos:leaders -c"
3036 if jsonFormat:
3037 cmdStr += " -j"
3038 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003039 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003040 return output
Jon Hallc6793552016-01-19 14:18:37 -08003041 except AssertionError:
3042 main.log.exception( "" )
3043 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003044 except TypeError:
3045 main.log.exception( self.name + ": Object not as expected" )
3046 return None
3047 except pexpect.EOF:
3048 main.log.error( self.name + ": EOF exception found" )
3049 main.log.error( self.name + ": " + self.handle.before )
3050 main.cleanup()
3051 main.exit()
3052 except Exception:
3053 main.log.exception( self.name + ": Uncaught exception!" )
3054 main.cleanup()
3055 main.exit()
3056
Jon Hallc6793552016-01-19 14:18:37 -08003057 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003058 """
3059 Returns a list in format [leader,candidate1,candidate2,...] for a given
3060 topic parameter and an empty list if the topic doesn't exist
3061 If no leader is elected leader in the returned list will be "none"
3062 Returns None if there is a type error processing the json object
3063 """
3064 try:
Jon Hall6e709752016-02-01 13:38:46 -08003065 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003066 rawOutput = self.sendline( cmdStr )
3067 assert "Command not found:" not in rawOutput, rawOutput
3068 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003069 results = []
3070 for dict in output:
3071 if dict["topic"] == topic:
3072 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003073 candidates = re.split( ", ", dict["candidates"][1:-1] )
3074 results.append( leader )
3075 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003076 return results
Jon Hallc6793552016-01-19 14:18:37 -08003077 except AssertionError:
3078 main.log.exception( "" )
3079 return None
3080 except ( TypeError, ValueError ):
3081 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003082 return None
3083 except pexpect.EOF:
3084 main.log.error( self.name + ": EOF exception found" )
3085 main.log.error( self.name + ": " + self.handle.before )
3086 main.cleanup()
3087 main.exit()
3088 except Exception:
3089 main.log.exception( self.name + ": Uncaught exception!" )
3090 main.cleanup()
3091 main.exit()
3092
Jon Hall61282e32015-03-19 11:34:11 -07003093 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003094 """
3095 Returns the output of the intent Pending map.
3096 """
Jon Hall63604932015-02-26 17:09:50 -08003097 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003098 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003099 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003100 cmdStr += " -j"
3101 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003102 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003103 return output
Jon Hallc6793552016-01-19 14:18:37 -08003104 except AssertionError:
3105 main.log.exception( "" )
3106 return None
Jon Hall63604932015-02-26 17:09:50 -08003107 except TypeError:
3108 main.log.exception( self.name + ": Object not as expected" )
3109 return None
3110 except pexpect.EOF:
3111 main.log.error( self.name + ": EOF exception found" )
3112 main.log.error( self.name + ": " + self.handle.before )
3113 main.cleanup()
3114 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003115 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003116 main.log.exception( self.name + ": Uncaught exception!" )
3117 main.cleanup()
3118 main.exit()
3119
Jon Hall61282e32015-03-19 11:34:11 -07003120 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003121 """
3122 Returns the output of the raft partitions command for ONOS.
3123 """
Jon Hall61282e32015-03-19 11:34:11 -07003124 # Sample JSON
3125 # {
3126 # "leader": "tcp://10.128.30.11:7238",
3127 # "members": [
3128 # "tcp://10.128.30.11:7238",
3129 # "tcp://10.128.30.17:7238",
3130 # "tcp://10.128.30.13:7238",
3131 # ],
3132 # "name": "p1",
3133 # "term": 3
3134 # },
Jon Hall63604932015-02-26 17:09:50 -08003135 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003136 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003137 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003138 cmdStr += " -j"
3139 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003140 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003141 return output
Jon Hallc6793552016-01-19 14:18:37 -08003142 except AssertionError:
3143 main.log.exception( "" )
3144 return None
Jon Hall63604932015-02-26 17:09:50 -08003145 except TypeError:
3146 main.log.exception( self.name + ": Object not as expected" )
3147 return None
3148 except pexpect.EOF:
3149 main.log.error( self.name + ": EOF exception found" )
3150 main.log.error( self.name + ": " + self.handle.before )
3151 main.cleanup()
3152 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003153 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003154 main.log.exception( self.name + ": Uncaught exception!" )
3155 main.cleanup()
3156 main.exit()
3157
Jon Hallbe379602015-03-24 13:39:32 -07003158 def apps( self, jsonFormat=True ):
3159 """
3160 Returns the output of the apps command for ONOS. This command lists
3161 information about installed ONOS applications
3162 """
3163 # Sample JSON object
3164 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3165 # "description":"ONOS OpenFlow protocol southbound providers",
3166 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3167 # "features":"[onos-openflow]","state":"ACTIVE"}]
3168 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003169 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003170 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003171 cmdStr += " -j"
3172 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003173 assert "Command not found:" not in output, output
3174 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003175 return output
Jon Hallbe379602015-03-24 13:39:32 -07003176 # FIXME: look at specific exceptions/Errors
3177 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003178 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003179 return None
3180 except TypeError:
3181 main.log.exception( self.name + ": Object not as expected" )
3182 return None
3183 except pexpect.EOF:
3184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
3186 main.cleanup()
3187 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003188 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003189 main.log.exception( self.name + ": Uncaught exception!" )
3190 main.cleanup()
3191 main.exit()
3192
Jon Hall146f1522015-03-24 15:33:24 -07003193 def appStatus( self, appName ):
3194 """
3195 Uses the onos:apps cli command to return the status of an application.
3196 Returns:
3197 "ACTIVE" - If app is installed and activated
3198 "INSTALLED" - If app is installed and deactivated
3199 "UNINSTALLED" - If app is not installed
3200 None - on error
3201 """
Jon Hall146f1522015-03-24 15:33:24 -07003202 try:
3203 if not isinstance( appName, types.StringType ):
3204 main.log.error( self.name + ".appStatus(): appName must be" +
3205 " a string" )
3206 return None
3207 output = self.apps( jsonFormat=True )
3208 appsJson = json.loads( output )
3209 state = None
3210 for app in appsJson:
3211 if appName == app.get('name'):
3212 state = app.get('state')
3213 break
3214 if state == "ACTIVE" or state == "INSTALLED":
3215 return state
3216 elif state is None:
3217 return "UNINSTALLED"
3218 elif state:
3219 main.log.error( "Unexpected state from 'onos:apps': " +
3220 str( state ) )
3221 return state
Jon Hallc6793552016-01-19 14:18:37 -08003222 except ( TypeError, ValueError ):
3223 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003224 return None
3225 except pexpect.EOF:
3226 main.log.error( self.name + ": EOF exception found" )
3227 main.log.error( self.name + ": " + self.handle.before )
3228 main.cleanup()
3229 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003230 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003231 main.log.exception( self.name + ": Uncaught exception!" )
3232 main.cleanup()
3233 main.exit()
3234
Jon Hallbe379602015-03-24 13:39:32 -07003235 def app( self, appName, option ):
3236 """
3237 Interacts with the app command for ONOS. This command manages
3238 application inventory.
3239 """
Jon Hallbe379602015-03-24 13:39:32 -07003240 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003241 # Validate argument types
3242 valid = True
3243 if not isinstance( appName, types.StringType ):
3244 main.log.error( self.name + ".app(): appName must be a " +
3245 "string" )
3246 valid = False
3247 if not isinstance( option, types.StringType ):
3248 main.log.error( self.name + ".app(): option must be a string" )
3249 valid = False
3250 if not valid:
3251 return main.FALSE
3252 # Validate Option
3253 option = option.lower()
3254 # NOTE: Install may become a valid option
3255 if option == "activate":
3256 pass
3257 elif option == "deactivate":
3258 pass
3259 elif option == "uninstall":
3260 pass
3261 else:
3262 # Invalid option
3263 main.log.error( "The ONOS app command argument only takes " +
3264 "the values: (activate|deactivate|uninstall)" +
3265 "; was given '" + option + "'")
3266 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003267 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003268 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003269 if "Error executing command" in output:
3270 main.log.error( "Error in processing onos:app command: " +
3271 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003272 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003273 elif "No such application" in output:
3274 main.log.error( "The application '" + appName +
3275 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003276 return main.FALSE
3277 elif "Command not found:" in output:
3278 main.log.error( "Error in processing onos:app command: " +
3279 str( output ) )
3280 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003281 elif "Unsupported command:" in output:
3282 main.log.error( "Incorrect command given to 'app': " +
3283 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003284 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003285 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003286 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003287 return main.TRUE
3288 except TypeError:
3289 main.log.exception( self.name + ": Object not as expected" )
3290 return main.ERROR
3291 except pexpect.EOF:
3292 main.log.error( self.name + ": EOF exception found" )
3293 main.log.error( self.name + ": " + self.handle.before )
3294 main.cleanup()
3295 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003296 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003297 main.log.exception( self.name + ": Uncaught exception!" )
3298 main.cleanup()
3299 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003300
Jon Hallbd16b922015-03-26 17:53:15 -07003301 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003302 """
3303 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003304 appName is the hierarchical app name, not the feature name
3305 If check is True, method will check the status of the app after the
3306 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003307 Returns main.TRUE if the command was successfully sent
3308 main.FALSE if the cli responded with an error or given
3309 incorrect input
3310 """
3311 try:
3312 if not isinstance( appName, types.StringType ):
3313 main.log.error( self.name + ".activateApp(): appName must be" +
3314 " a string" )
3315 return main.FALSE
3316 status = self.appStatus( appName )
3317 if status == "INSTALLED":
3318 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003319 if check and response == main.TRUE:
3320 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003321 status = self.appStatus( appName )
3322 if status == "ACTIVE":
3323 return main.TRUE
3324 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003325 main.log.debug( "The state of application " +
3326 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003327 time.sleep( 1 )
3328 return main.FALSE
3329 else: # not 'check' or command didn't succeed
3330 return response
Jon Hall146f1522015-03-24 15:33:24 -07003331 elif status == "ACTIVE":
3332 return main.TRUE
3333 elif status == "UNINSTALLED":
3334 main.log.error( self.name + ": Tried to activate the " +
3335 "application '" + appName + "' which is not " +
3336 "installed." )
3337 else:
3338 main.log.error( "Unexpected return value from appStatus: " +
3339 str( status ) )
3340 return main.ERROR
3341 except TypeError:
3342 main.log.exception( self.name + ": Object not as expected" )
3343 return main.ERROR
3344 except pexpect.EOF:
3345 main.log.error( self.name + ": EOF exception found" )
3346 main.log.error( self.name + ": " + self.handle.before )
3347 main.cleanup()
3348 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003349 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003350 main.log.exception( self.name + ": Uncaught exception!" )
3351 main.cleanup()
3352 main.exit()
3353
Jon Hallbd16b922015-03-26 17:53:15 -07003354 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003355 """
3356 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003357 appName is the hierarchical app name, not the feature name
3358 If check is True, method will check the status of the app after the
3359 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003360 Returns main.TRUE if the command was successfully sent
3361 main.FALSE if the cli responded with an error or given
3362 incorrect input
3363 """
3364 try:
3365 if not isinstance( appName, types.StringType ):
3366 main.log.error( self.name + ".deactivateApp(): appName must " +
3367 "be a string" )
3368 return main.FALSE
3369 status = self.appStatus( appName )
3370 if status == "INSTALLED":
3371 return main.TRUE
3372 elif status == "ACTIVE":
3373 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003374 if check and response == main.TRUE:
3375 for i in range(10): # try 10 times then give up
3376 status = self.appStatus( appName )
3377 if status == "INSTALLED":
3378 return main.TRUE
3379 else:
3380 time.sleep( 1 )
3381 return main.FALSE
3382 else: # not check or command didn't succeed
3383 return response
Jon Hall146f1522015-03-24 15:33:24 -07003384 elif status == "UNINSTALLED":
3385 main.log.warn( self.name + ": Tried to deactivate the " +
3386 "application '" + appName + "' which is not " +
3387 "installed." )
3388 return main.TRUE
3389 else:
3390 main.log.error( "Unexpected return value from appStatus: " +
3391 str( status ) )
3392 return main.ERROR
3393 except TypeError:
3394 main.log.exception( self.name + ": Object not as expected" )
3395 return main.ERROR
3396 except pexpect.EOF:
3397 main.log.error( self.name + ": EOF exception found" )
3398 main.log.error( self.name + ": " + self.handle.before )
3399 main.cleanup()
3400 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003401 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003402 main.log.exception( self.name + ": Uncaught exception!" )
3403 main.cleanup()
3404 main.exit()
3405
Jon Hallbd16b922015-03-26 17:53:15 -07003406 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003407 """
3408 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003409 appName is the hierarchical app name, not the feature name
3410 If check is True, method will check the status of the app after the
3411 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003412 Returns main.TRUE if the command was successfully sent
3413 main.FALSE if the cli responded with an error or given
3414 incorrect input
3415 """
3416 # TODO: check with Thomas about the state machine for apps
3417 try:
3418 if not isinstance( appName, types.StringType ):
3419 main.log.error( self.name + ".uninstallApp(): appName must " +
3420 "be a string" )
3421 return main.FALSE
3422 status = self.appStatus( appName )
3423 if status == "INSTALLED":
3424 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003425 if check and response == main.TRUE:
3426 for i in range(10): # try 10 times then give up
3427 status = self.appStatus( appName )
3428 if status == "UNINSTALLED":
3429 return main.TRUE
3430 else:
3431 time.sleep( 1 )
3432 return main.FALSE
3433 else: # not check or command didn't succeed
3434 return response
Jon Hall146f1522015-03-24 15:33:24 -07003435 elif status == "ACTIVE":
3436 main.log.warn( self.name + ": Tried to uninstall the " +
3437 "application '" + appName + "' which is " +
3438 "currently active." )
3439 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003440 if check and response == main.TRUE:
3441 for i in range(10): # try 10 times then give up
3442 status = self.appStatus( appName )
3443 if status == "UNINSTALLED":
3444 return main.TRUE
3445 else:
3446 time.sleep( 1 )
3447 return main.FALSE
3448 else: # not check or command didn't succeed
3449 return response
Jon Hall146f1522015-03-24 15:33:24 -07003450 elif status == "UNINSTALLED":
3451 return main.TRUE
3452 else:
3453 main.log.error( "Unexpected return value from appStatus: " +
3454 str( status ) )
3455 return main.ERROR
3456 except TypeError:
3457 main.log.exception( self.name + ": Object not as expected" )
3458 return main.ERROR
3459 except pexpect.EOF:
3460 main.log.error( self.name + ": EOF exception found" )
3461 main.log.error( self.name + ": " + self.handle.before )
3462 main.cleanup()
3463 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003464 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003465 main.log.exception( self.name + ": Uncaught exception!" )
3466 main.cleanup()
3467 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003468
3469 def appIDs( self, jsonFormat=True ):
3470 """
3471 Show the mappings between app id and app names given by the 'app-ids'
3472 cli command
3473 """
3474 try:
3475 cmdStr = "app-ids"
3476 if jsonFormat:
3477 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003478 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003479 assert "Command not found:" not in output, output
3480 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003481 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003482 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003483 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003484 return None
3485 except TypeError:
3486 main.log.exception( self.name + ": Object not as expected" )
3487 return None
3488 except pexpect.EOF:
3489 main.log.error( self.name + ": EOF exception found" )
3490 main.log.error( self.name + ": " + self.handle.before )
3491 main.cleanup()
3492 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003493 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003494 main.log.exception( self.name + ": Uncaught exception!" )
3495 main.cleanup()
3496 main.exit()
3497
3498 def appToIDCheck( self ):
3499 """
3500 This method will check that each application's ID listed in 'apps' is
3501 the same as the ID listed in 'app-ids'. The check will also check that
3502 there are no duplicate IDs issued. Note that an app ID should be
3503 a globaly unique numerical identifier for app/app-like features. Once
3504 an ID is registered, the ID is never freed up so that if an app is
3505 reinstalled it will have the same ID.
3506
3507 Returns: main.TRUE if the check passes and
3508 main.FALSE if the check fails or
3509 main.ERROR if there is some error in processing the test
3510 """
3511 try:
Jon Hall390696c2015-05-05 17:13:41 -07003512 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003513 rawJson = self.appIDs( jsonFormat=True )
3514 if rawJson:
3515 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003516 else:
Jon Hallc6793552016-01-19 14:18:37 -08003517 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003518 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003519 rawJson = self.apps( jsonFormat=True )
3520 if rawJson:
3521 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003522 else:
Jon Hallc6793552016-01-19 14:18:37 -08003523 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003524 bail = True
3525 if bail:
3526 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003527 result = main.TRUE
3528 for app in apps:
3529 appID = app.get( 'id' )
3530 if appID is None:
3531 main.log.error( "Error parsing app: " + str( app ) )
3532 result = main.FALSE
3533 appName = app.get( 'name' )
3534 if appName is None:
3535 main.log.error( "Error parsing app: " + str( app ) )
3536 result = main.FALSE
3537 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003538 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003539 # main.log.debug( "Comparing " + str( app ) + " to " +
3540 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003541 if not current: # if ids doesn't have this id
3542 result = main.FALSE
3543 main.log.error( "'app-ids' does not have the ID for " +
3544 str( appName ) + " that apps does." )
3545 elif len( current ) > 1:
3546 # there is more than one app with this ID
3547 result = main.FALSE
3548 # We will log this later in the method
3549 elif not current[0][ 'name' ] == appName:
3550 currentName = current[0][ 'name' ]
3551 result = main.FALSE
3552 main.log.error( "'app-ids' has " + str( currentName ) +
3553 " registered under id:" + str( appID ) +
3554 " but 'apps' has " + str( appName ) )
3555 else:
3556 pass # id and name match!
3557 # now make sure that app-ids has no duplicates
3558 idsList = []
3559 namesList = []
3560 for item in ids:
3561 idsList.append( item[ 'id' ] )
3562 namesList.append( item[ 'name' ] )
3563 if len( idsList ) != len( set( idsList ) ) or\
3564 len( namesList ) != len( set( namesList ) ):
3565 main.log.error( "'app-ids' has some duplicate entries: \n"
3566 + json.dumps( ids,
3567 sort_keys=True,
3568 indent=4,
3569 separators=( ',', ': ' ) ) )
3570 result = main.FALSE
3571 return result
Jon Hallc6793552016-01-19 14:18:37 -08003572 except ( TypeError, ValueError ):
3573 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003574 return main.ERROR
3575 except pexpect.EOF:
3576 main.log.error( self.name + ": EOF exception found" )
3577 main.log.error( self.name + ": " + self.handle.before )
3578 main.cleanup()
3579 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003580 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003581 main.log.exception( self.name + ": Uncaught exception!" )
3582 main.cleanup()
3583 main.exit()
3584
Jon Hallfb760a02015-04-13 15:35:03 -07003585 def getCfg( self, component=None, propName=None, short=False,
3586 jsonFormat=True ):
3587 """
3588 Get configuration settings from onos cli
3589 Optional arguments:
3590 component - Optionally only list configurations for a specific
3591 component. If None, all components with configurations
3592 are displayed. Case Sensitive string.
3593 propName - If component is specified, propName option will show
3594 only this specific configuration from that component.
3595 Case Sensitive string.
3596 jsonFormat - Returns output as json. Note that this will override
3597 the short option
3598 short - Short, less verbose, version of configurations.
3599 This is overridden by the json option
3600 returns:
3601 Output from cli as a string or None on error
3602 """
3603 try:
3604 baseStr = "cfg"
3605 cmdStr = " get"
3606 componentStr = ""
3607 if component:
3608 componentStr += " " + component
3609 if propName:
3610 componentStr += " " + propName
3611 if jsonFormat:
3612 baseStr += " -j"
3613 elif short:
3614 baseStr += " -s"
3615 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003616 assert "Command not found:" not in output, output
3617 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003618 return output
3619 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003620 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003621 return None
3622 except TypeError:
3623 main.log.exception( self.name + ": Object not as expected" )
3624 return None
3625 except pexpect.EOF:
3626 main.log.error( self.name + ": EOF exception found" )
3627 main.log.error( self.name + ": " + self.handle.before )
3628 main.cleanup()
3629 main.exit()
3630 except Exception:
3631 main.log.exception( self.name + ": Uncaught exception!" )
3632 main.cleanup()
3633 main.exit()
3634
3635 def setCfg( self, component, propName, value=None, check=True ):
3636 """
3637 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003638 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003639 component - The case sensitive name of the component whose
3640 property is to be set
3641 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003642 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003643 value - The value to set the property to. If None, will unset the
3644 property and revert it to it's default value(if applicable)
3645 check - Boolean, Check whether the option was successfully set this
3646 only applies when a value is given.
3647 returns:
3648 main.TRUE on success or main.FALSE on failure. If check is False,
3649 will return main.TRUE unless there is an error
3650 """
3651 try:
3652 baseStr = "cfg"
3653 cmdStr = " set " + str( component ) + " " + str( propName )
3654 if value is not None:
3655 cmdStr += " " + str( value )
3656 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003657 assert "Command not found:" not in output, output
3658 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003659 if value and check:
3660 results = self.getCfg( component=str( component ),
3661 propName=str( propName ),
3662 jsonFormat=True )
3663 # Check if current value is what we just set
3664 try:
3665 jsonOutput = json.loads( results )
3666 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003667 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003668 main.log.exception( "Error parsing cfg output" )
3669 main.log.error( "output:" + repr( results ) )
3670 return main.FALSE
3671 if current == str( value ):
3672 return main.TRUE
3673 return main.FALSE
3674 return main.TRUE
3675 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003676 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003677 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003678 except ( TypeError, ValueError ):
3679 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003680 return main.FALSE
3681 except pexpect.EOF:
3682 main.log.error( self.name + ": EOF exception found" )
3683 main.log.error( self.name + ": " + self.handle.before )
3684 main.cleanup()
3685 main.exit()
3686 except Exception:
3687 main.log.exception( self.name + ": Uncaught exception!" )
3688 main.cleanup()
3689 main.exit()
3690
Jon Hall390696c2015-05-05 17:13:41 -07003691 def setTestAdd( self, setName, values ):
3692 """
3693 CLI command to add elements to a distributed set.
3694 Arguments:
3695 setName - The name of the set to add to.
3696 values - The value(s) to add to the set, space seperated.
3697 Example usages:
3698 setTestAdd( "set1", "a b c" )
3699 setTestAdd( "set2", "1" )
3700 returns:
3701 main.TRUE on success OR
3702 main.FALSE if elements were already in the set OR
3703 main.ERROR on error
3704 """
3705 try:
3706 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3707 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003708 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003709 try:
3710 # TODO: Maybe make this less hardcoded
3711 # ConsistentMap Exceptions
3712 assert "org.onosproject.store.service" not in output
3713 # Node not leader
3714 assert "java.lang.IllegalStateException" not in output
3715 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003716 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003717 "command: " + str( output ) )
3718 retryTime = 30 # Conservative time, given by Madan
3719 main.log.info( "Waiting " + str( retryTime ) +
3720 "seconds before retrying." )
3721 time.sleep( retryTime ) # Due to change in mastership
3722 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003723 assert "Error executing command" not in output
3724 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3725 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3726 main.log.info( self.name + ": " + output )
3727 if re.search( positiveMatch, output):
3728 return main.TRUE
3729 elif re.search( negativeMatch, output):
3730 return main.FALSE
3731 else:
3732 main.log.error( self.name + ": setTestAdd did not" +
3733 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003734 main.log.debug( self.name + " actual: " + repr( output ) )
3735 return main.ERROR
3736 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003737 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003738 return main.ERROR
3739 except TypeError:
3740 main.log.exception( self.name + ": Object not as expected" )
3741 return main.ERROR
3742 except pexpect.EOF:
3743 main.log.error( self.name + ": EOF exception found" )
3744 main.log.error( self.name + ": " + self.handle.before )
3745 main.cleanup()
3746 main.exit()
3747 except Exception:
3748 main.log.exception( self.name + ": Uncaught exception!" )
3749 main.cleanup()
3750 main.exit()
3751
3752 def setTestRemove( self, setName, values, clear=False, retain=False ):
3753 """
3754 CLI command to remove elements from a distributed set.
3755 Required arguments:
3756 setName - The name of the set to remove from.
3757 values - The value(s) to remove from the set, space seperated.
3758 Optional arguments:
3759 clear - Clear all elements from the set
3760 retain - Retain only the given values. (intersection of the
3761 original set and the given set)
3762 returns:
3763 main.TRUE on success OR
3764 main.FALSE if the set was not changed OR
3765 main.ERROR on error
3766 """
3767 try:
3768 cmdStr = "set-test-remove "
3769 if clear:
3770 cmdStr += "-c " + str( setName )
3771 elif retain:
3772 cmdStr += "-r " + str( setName ) + " " + str( values )
3773 else:
3774 cmdStr += str( setName ) + " " + str( values )
3775 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003776 try:
3777 # TODO: Maybe make this less hardcoded
3778 # ConsistentMap Exceptions
3779 assert "org.onosproject.store.service" not in output
3780 # Node not leader
3781 assert "java.lang.IllegalStateException" not in output
3782 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003783 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003784 "command: " + str( output ) )
3785 retryTime = 30 # Conservative time, given by Madan
3786 main.log.info( "Waiting " + str( retryTime ) +
3787 "seconds before retrying." )
3788 time.sleep( retryTime ) # Due to change in mastership
3789 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003790 assert "Command not found:" not in output, output
3791 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003792 main.log.info( self.name + ": " + output )
3793 if clear:
3794 pattern = "Set " + str( setName ) + " cleared"
3795 if re.search( pattern, output ):
3796 return main.TRUE
3797 elif retain:
3798 positivePattern = str( setName ) + " was pruned to contain " +\
3799 "only elements of set \[(.*)\]"
3800 negativePattern = str( setName ) + " was not changed by " +\
3801 "retaining only elements of the set " +\
3802 "\[(.*)\]"
3803 if re.search( positivePattern, output ):
3804 return main.TRUE
3805 elif re.search( negativePattern, output ):
3806 return main.FALSE
3807 else:
3808 positivePattern = "\[(.*)\] was removed from the set " +\
3809 str( setName )
3810 if ( len( values.split() ) == 1 ):
3811 negativePattern = "\[(.*)\] was not in set " +\
3812 str( setName )
3813 else:
3814 negativePattern = "No element of \[(.*)\] was in set " +\
3815 str( setName )
3816 if re.search( positivePattern, output ):
3817 return main.TRUE
3818 elif re.search( negativePattern, output ):
3819 return main.FALSE
3820 main.log.error( self.name + ": setTestRemove did not" +
3821 " match expected output" )
3822 main.log.debug( self.name + " expected: " + pattern )
3823 main.log.debug( self.name + " actual: " + repr( output ) )
3824 return main.ERROR
3825 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003826 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003827 return main.ERROR
3828 except TypeError:
3829 main.log.exception( self.name + ": Object not as expected" )
3830 return main.ERROR
3831 except pexpect.EOF:
3832 main.log.error( self.name + ": EOF exception found" )
3833 main.log.error( self.name + ": " + self.handle.before )
3834 main.cleanup()
3835 main.exit()
3836 except Exception:
3837 main.log.exception( self.name + ": Uncaught exception!" )
3838 main.cleanup()
3839 main.exit()
3840
3841 def setTestGet( self, setName, values="" ):
3842 """
3843 CLI command to get the elements in a distributed set.
3844 Required arguments:
3845 setName - The name of the set to remove from.
3846 Optional arguments:
3847 values - The value(s) to check if in the set, space seperated.
3848 returns:
3849 main.ERROR on error OR
3850 A list of elements in the set if no optional arguments are
3851 supplied OR
3852 A tuple containing the list then:
3853 main.FALSE if the given values are not in the set OR
3854 main.TRUE if the given values are in the set OR
3855 """
3856 try:
3857 values = str( values ).strip()
3858 setName = str( setName ).strip()
3859 length = len( values.split() )
3860 containsCheck = None
3861 # Patterns to match
3862 setPattern = "\[(.*)\]"
3863 pattern = "Items in set " + setName + ":\n" + setPattern
3864 containsTrue = "Set " + setName + " contains the value " + values
3865 containsFalse = "Set " + setName + " did not contain the value " +\
3866 values
3867 containsAllTrue = "Set " + setName + " contains the the subset " +\
3868 setPattern
3869 containsAllFalse = "Set " + setName + " did not contain the the" +\
3870 " subset " + setPattern
3871
3872 cmdStr = "set-test-get "
3873 cmdStr += setName + " " + values
3874 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003875 try:
3876 # TODO: Maybe make this less hardcoded
3877 # ConsistentMap Exceptions
3878 assert "org.onosproject.store.service" not in output
3879 # Node not leader
3880 assert "java.lang.IllegalStateException" not in output
3881 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003882 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003883 "command: " + str( output ) )
3884 retryTime = 30 # Conservative time, given by Madan
3885 main.log.info( "Waiting " + str( retryTime ) +
3886 "seconds before retrying." )
3887 time.sleep( retryTime ) # Due to change in mastership
3888 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003889 assert "Command not found:" not in output, output
3890 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003891 main.log.info( self.name + ": " + output )
3892
3893 if length == 0:
3894 match = re.search( pattern, output )
3895 else: # if given values
3896 if length == 1: # Contains output
3897 patternTrue = pattern + "\n" + containsTrue
3898 patternFalse = pattern + "\n" + containsFalse
3899 else: # ContainsAll output
3900 patternTrue = pattern + "\n" + containsAllTrue
3901 patternFalse = pattern + "\n" + containsAllFalse
3902 matchTrue = re.search( patternTrue, output )
3903 matchFalse = re.search( patternFalse, output )
3904 if matchTrue:
3905 containsCheck = main.TRUE
3906 match = matchTrue
3907 elif matchFalse:
3908 containsCheck = main.FALSE
3909 match = matchFalse
3910 else:
3911 main.log.error( self.name + " setTestGet did not match " +\
3912 "expected output" )
3913 main.log.debug( self.name + " expected: " + pattern )
3914 main.log.debug( self.name + " actual: " + repr( output ) )
3915 match = None
3916 if match:
3917 setMatch = match.group( 1 )
3918 if setMatch == '':
3919 setList = []
3920 else:
3921 setList = setMatch.split( ", " )
3922 if length > 0:
3923 return ( setList, containsCheck )
3924 else:
3925 return setList
3926 else: # no match
3927 main.log.error( self.name + ": setTestGet did not" +
3928 " match expected output" )
3929 main.log.debug( self.name + " expected: " + pattern )
3930 main.log.debug( self.name + " actual: " + repr( output ) )
3931 return main.ERROR
3932 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003933 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07003934 return main.ERROR
3935 except TypeError:
3936 main.log.exception( self.name + ": Object not as expected" )
3937 return main.ERROR
3938 except pexpect.EOF:
3939 main.log.error( self.name + ": EOF exception found" )
3940 main.log.error( self.name + ": " + self.handle.before )
3941 main.cleanup()
3942 main.exit()
3943 except Exception:
3944 main.log.exception( self.name + ": Uncaught exception!" )
3945 main.cleanup()
3946 main.exit()
3947
3948 def setTestSize( self, setName ):
3949 """
3950 CLI command to get the elements in a distributed set.
3951 Required arguments:
3952 setName - The name of the set to remove from.
3953 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07003954 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07003955 None on error
3956 """
3957 try:
3958 # TODO: Should this check against the number of elements returned
3959 # and then return true/false based on that?
3960 setName = str( setName ).strip()
3961 # Patterns to match
3962 setPattern = "\[(.*)\]"
3963 pattern = "There are (\d+) items in set " + setName + ":\n" +\
3964 setPattern
3965 cmdStr = "set-test-get -s "
3966 cmdStr += setName
3967 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003968 try:
3969 # TODO: Maybe make this less hardcoded
3970 # ConsistentMap Exceptions
3971 assert "org.onosproject.store.service" not in output
3972 # Node not leader
3973 assert "java.lang.IllegalStateException" not in output
3974 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003975 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003976 "command: " + str( output ) )
3977 retryTime = 30 # Conservative time, given by Madan
3978 main.log.info( "Waiting " + str( retryTime ) +
3979 "seconds before retrying." )
3980 time.sleep( retryTime ) # Due to change in mastership
3981 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003982 assert "Command not found:" not in output, output
3983 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003984 main.log.info( self.name + ": " + output )
3985 match = re.search( pattern, output )
3986 if match:
3987 setSize = int( match.group( 1 ) )
3988 setMatch = match.group( 2 )
3989 if len( setMatch.split() ) == setSize:
3990 main.log.info( "The size returned by " + self.name +
3991 " matches the number of elements in " +
3992 "the returned set" )
3993 else:
3994 main.log.error( "The size returned by " + self.name +
3995 " does not match the number of " +
3996 "elements in the returned set." )
3997 return setSize
3998 else: # no match
3999 main.log.error( self.name + ": setTestGet did not" +
4000 " match expected output" )
4001 main.log.debug( self.name + " expected: " + pattern )
4002 main.log.debug( self.name + " actual: " + repr( output ) )
4003 return None
4004 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004005 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004006 return None
Jon Hall390696c2015-05-05 17:13:41 -07004007 except TypeError:
4008 main.log.exception( self.name + ": Object not as expected" )
4009 return None
4010 except pexpect.EOF:
4011 main.log.error( self.name + ": EOF exception found" )
4012 main.log.error( self.name + ": " + self.handle.before )
4013 main.cleanup()
4014 main.exit()
4015 except Exception:
4016 main.log.exception( self.name + ": Uncaught exception!" )
4017 main.cleanup()
4018 main.exit()
4019
Jon Hall80daded2015-05-27 16:07:00 -07004020 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004021 """
4022 Command to list the various counters in the system.
4023 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004024 if jsonFormat, a string of the json object returned by the cli
4025 command
4026 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004027 None on error
4028 """
Jon Hall390696c2015-05-05 17:13:41 -07004029 try:
4030 counters = {}
4031 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004032 if jsonFormat:
4033 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004034 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004035 assert "Command not found:" not in output, output
4036 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004037 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004038 return output
Jon Hall390696c2015-05-05 17:13:41 -07004039 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004040 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004041 return None
Jon Hall390696c2015-05-05 17:13:41 -07004042 except TypeError:
4043 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004044 return None
Jon Hall390696c2015-05-05 17:13:41 -07004045 except pexpect.EOF:
4046 main.log.error( self.name + ": EOF exception found" )
4047 main.log.error( self.name + ": " + self.handle.before )
4048 main.cleanup()
4049 main.exit()
4050 except Exception:
4051 main.log.exception( self.name + ": Uncaught exception!" )
4052 main.cleanup()
4053 main.exit()
4054
Jon Hall935db192016-04-19 00:22:04 -07004055 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004056 """
Jon Halle1a3b752015-07-22 13:02:46 -07004057 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004058 Required arguments:
4059 counter - The name of the counter to increment.
4060 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004061 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004062 returns:
4063 integer value of the counter or
4064 None on Error
4065 """
4066 try:
4067 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004068 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004069 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004070 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004071 if delta != 1:
4072 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004073 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004074 try:
4075 # TODO: Maybe make this less hardcoded
4076 # ConsistentMap Exceptions
4077 assert "org.onosproject.store.service" not in output
4078 # Node not leader
4079 assert "java.lang.IllegalStateException" not in output
4080 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004081 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004082 "command: " + str( output ) )
4083 retryTime = 30 # Conservative time, given by Madan
4084 main.log.info( "Waiting " + str( retryTime ) +
4085 "seconds before retrying." )
4086 time.sleep( retryTime ) # Due to change in mastership
4087 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004088 assert "Command not found:" not in output, output
4089 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004090 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004091 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004092 match = re.search( pattern, output )
4093 if match:
4094 return int( match.group( 1 ) )
4095 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004096 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004097 " match expected output." )
4098 main.log.debug( self.name + " expected: " + pattern )
4099 main.log.debug( self.name + " actual: " + repr( output ) )
4100 return None
4101 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004102 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004103 return None
4104 except TypeError:
4105 main.log.exception( self.name + ": Object not as expected" )
4106 return None
4107 except pexpect.EOF:
4108 main.log.error( self.name + ": EOF exception found" )
4109 main.log.error( self.name + ": " + self.handle.before )
4110 main.cleanup()
4111 main.exit()
4112 except Exception:
4113 main.log.exception( self.name + ": Uncaught exception!" )
4114 main.cleanup()
4115 main.exit()
4116
Jon Hall935db192016-04-19 00:22:04 -07004117 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004118 """
4119 CLI command to get a distributed counter then add a delta to it.
4120 Required arguments:
4121 counter - The name of the counter to increment.
4122 Optional arguments:
4123 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004124 returns:
4125 integer value of the counter or
4126 None on Error
4127 """
4128 try:
4129 counter = str( counter )
4130 delta = int( delta )
4131 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004132 cmdStr += counter
4133 if delta != 1:
4134 cmdStr += " " + str( delta )
4135 output = self.sendline( cmdStr )
4136 try:
4137 # TODO: Maybe make this less hardcoded
4138 # ConsistentMap Exceptions
4139 assert "org.onosproject.store.service" not in output
4140 # Node not leader
4141 assert "java.lang.IllegalStateException" not in output
4142 except AssertionError:
4143 main.log.error( "Error in processing '" + cmdStr + "' " +
4144 "command: " + str( output ) )
4145 retryTime = 30 # Conservative time, given by Madan
4146 main.log.info( "Waiting " + str( retryTime ) +
4147 "seconds before retrying." )
4148 time.sleep( retryTime ) # Due to change in mastership
4149 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004150 assert "Command not found:" not in output, output
4151 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004152 main.log.info( self.name + ": " + output )
4153 pattern = counter + " was updated to (-?\d+)"
4154 match = re.search( pattern, output )
4155 if match:
4156 return int( match.group( 1 ) )
4157 else:
4158 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4159 " match expected output." )
4160 main.log.debug( self.name + " expected: " + pattern )
4161 main.log.debug( self.name + " actual: " + repr( output ) )
4162 return None
4163 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004164 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004165 return None
4166 except TypeError:
4167 main.log.exception( self.name + ": Object not as expected" )
4168 return None
4169 except pexpect.EOF:
4170 main.log.error( self.name + ": EOF exception found" )
4171 main.log.error( self.name + ": " + self.handle.before )
4172 main.cleanup()
4173 main.exit()
4174 except Exception:
4175 main.log.exception( self.name + ": Uncaught exception!" )
4176 main.cleanup()
4177 main.exit()
4178
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004179 def summary( self, jsonFormat=True ):
4180 """
4181 Description: Execute summary command in onos
4182 Returns: json object ( summary -j ), returns main.FALSE if there is
4183 no output
4184
4185 """
4186 try:
4187 cmdStr = "summary"
4188 if jsonFormat:
4189 cmdStr += " -j"
4190 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004191 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004192 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004193 if not handle:
4194 main.log.error( self.name + ": There is no output in " +
4195 "summary command" )
4196 return main.FALSE
4197 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004198 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004199 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004200 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004201 except TypeError:
4202 main.log.exception( self.name + ": Object not as expected" )
4203 return None
4204 except pexpect.EOF:
4205 main.log.error( self.name + ": EOF exception found" )
4206 main.log.error( self.name + ": " + self.handle.before )
4207 main.cleanup()
4208 main.exit()
4209 except Exception:
4210 main.log.exception( self.name + ": Uncaught exception!" )
4211 main.cleanup()
4212 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004213
Jon Hall935db192016-04-19 00:22:04 -07004214 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004215 """
4216 CLI command to get the value of a key in a consistent map using
4217 transactions. This a test function and can only get keys from the
4218 test map hard coded into the cli command
4219 Required arguments:
4220 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004221 returns:
4222 The string value of the key or
4223 None on Error
4224 """
4225 try:
4226 keyName = str( keyName )
4227 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004228 cmdStr += keyName
4229 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004230 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004231 try:
4232 # TODO: Maybe make this less hardcoded
4233 # ConsistentMap Exceptions
4234 assert "org.onosproject.store.service" not in output
4235 # Node not leader
4236 assert "java.lang.IllegalStateException" not in output
4237 except AssertionError:
4238 main.log.error( "Error in processing '" + cmdStr + "' " +
4239 "command: " + str( output ) )
4240 return None
4241 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4242 if "Key " + keyName + " not found." in output:
4243 return None
4244 else:
4245 match = re.search( pattern, output )
4246 if match:
4247 return match.groupdict()[ 'value' ]
4248 else:
4249 main.log.error( self.name + ": transactionlMapGet did not" +
4250 " match expected output." )
4251 main.log.debug( self.name + " expected: " + pattern )
4252 main.log.debug( self.name + " actual: " + repr( output ) )
4253 return None
Jon Hallc6793552016-01-19 14:18:37 -08004254 except AssertionError:
4255 main.log.exception( "" )
4256 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004257 except TypeError:
4258 main.log.exception( self.name + ": Object not as expected" )
4259 return None
4260 except pexpect.EOF:
4261 main.log.error( self.name + ": EOF exception found" )
4262 main.log.error( self.name + ": " + self.handle.before )
4263 main.cleanup()
4264 main.exit()
4265 except Exception:
4266 main.log.exception( self.name + ": Uncaught exception!" )
4267 main.cleanup()
4268 main.exit()
4269
Jon Hall935db192016-04-19 00:22:04 -07004270 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004271 """
4272 CLI command to put a value into 'numKeys' number of keys in a
4273 consistent map using transactions. This a test function and can only
4274 put into keys named 'Key#' of the test map hard coded into the cli command
4275 Required arguments:
4276 numKeys - Number of keys to add the value to
4277 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004278 returns:
4279 A dictionary whose keys are the name of the keys put into the map
4280 and the values of the keys are dictionaries whose key-values are
4281 'value': value put into map and optionaly
4282 'oldValue': Previous value in the key or
4283 None on Error
4284
4285 Example output
4286 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4287 'Key2': {'value': 'Testing'} }
4288 """
4289 try:
4290 numKeys = str( numKeys )
4291 value = str( value )
4292 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004293 cmdStr += numKeys + " " + value
4294 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004295 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004296 try:
4297 # TODO: Maybe make this less hardcoded
4298 # ConsistentMap Exceptions
4299 assert "org.onosproject.store.service" not in output
4300 # Node not leader
4301 assert "java.lang.IllegalStateException" not in output
4302 except AssertionError:
4303 main.log.error( "Error in processing '" + cmdStr + "' " +
4304 "command: " + str( output ) )
4305 return None
4306 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4307 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4308 results = {}
4309 for line in output.splitlines():
4310 new = re.search( newPattern, line )
4311 updated = re.search( updatedPattern, line )
4312 if new:
4313 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4314 elif updated:
4315 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004316 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004317 else:
4318 main.log.error( self.name + ": transactionlMapGet did not" +
4319 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004320 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4321 newPattern,
4322 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004323 main.log.debug( self.name + " actual: " + repr( output ) )
4324 return results
Jon Hallc6793552016-01-19 14:18:37 -08004325 except AssertionError:
4326 main.log.exception( "" )
4327 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004328 except TypeError:
4329 main.log.exception( self.name + ": Object not as expected" )
4330 return None
4331 except pexpect.EOF:
4332 main.log.error( self.name + ": EOF exception found" )
4333 main.log.error( self.name + ": " + self.handle.before )
4334 main.cleanup()
4335 main.exit()
4336 except Exception:
4337 main.log.exception( self.name + ": Uncaught exception!" )
4338 main.cleanup()
4339 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004340
acsmarsdaea66c2015-09-03 11:44:06 -07004341 def maps( self, jsonFormat=True ):
4342 """
4343 Description: Returns result of onos:maps
4344 Optional:
4345 * jsonFormat: enable json formatting of output
4346 """
4347 try:
4348 cmdStr = "maps"
4349 if jsonFormat:
4350 cmdStr += " -j"
4351 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004352 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004353 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004354 except AssertionError:
4355 main.log.exception( "" )
4356 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004357 except TypeError:
4358 main.log.exception( self.name + ": Object not as expected" )
4359 return None
4360 except pexpect.EOF:
4361 main.log.error( self.name + ": EOF exception found" )
4362 main.log.error( self.name + ": " + self.handle.before )
4363 main.cleanup()
4364 main.exit()
4365 except Exception:
4366 main.log.exception( self.name + ": Uncaught exception!" )
4367 main.cleanup()
4368 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004369
4370 def getSwController( self, uri, jsonFormat=True ):
4371 """
4372 Descrition: Gets the controller information from the device
4373 """
4374 try:
4375 cmd = "device-controllers "
4376 if jsonFormat:
4377 cmd += "-j "
4378 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004379 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004380 return response
Jon Hallc6793552016-01-19 14:18:37 -08004381 except AssertionError:
4382 main.log.exception( "" )
4383 return None
GlennRC050596c2015-11-18 17:06:41 -08004384 except TypeError:
4385 main.log.exception( self.name + ": Object not as expected" )
4386 return None
4387 except pexpect.EOF:
4388 main.log.error( self.name + ": EOF exception found" )
4389 main.log.error( self.name + ": " + self.handle.before )
4390 main.cleanup()
4391 main.exit()
4392 except Exception:
4393 main.log.exception( self.name + ": Uncaught exception!" )
4394 main.cleanup()
4395 main.exit()
4396
4397 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4398 """
4399 Descrition: sets the controller(s) for the specified device
4400
4401 Parameters:
4402 Required: uri - String: The uri of the device(switch).
4403 ip - String or List: The ip address of the controller.
4404 This parameter can be formed in a couple of different ways.
4405 VALID:
4406 10.0.0.1 - just the ip address
4407 tcp:10.0.0.1 - the protocol and the ip address
4408 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4409 so that you can add controllers with different
4410 protocols and ports
4411 INVALID:
4412 10.0.0.1:6653 - this is not supported by ONOS
4413
4414 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4415 port - The port number.
4416 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4417
4418 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4419 """
4420 try:
4421 cmd = "device-setcontrollers"
4422
4423 if jsonFormat:
4424 cmd += " -j"
4425 cmd += " " + uri
4426 if isinstance( ip, str ):
4427 ip = [ip]
4428 for item in ip:
4429 if ":" in item:
4430 sitem = item.split( ":" )
4431 if len(sitem) == 3:
4432 cmd += " " + item
4433 elif "." in sitem[1]:
4434 cmd += " {}:{}".format(item, port)
4435 else:
4436 main.log.error( "Malformed entry: " + item )
4437 raise TypeError
4438 else:
4439 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004440 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004441 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004442 if "Error" in response:
4443 main.log.error( response )
4444 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004445 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004446 except AssertionError:
4447 main.log.exception( "" )
4448 return None
GlennRC050596c2015-11-18 17:06:41 -08004449 except TypeError:
4450 main.log.exception( self.name + ": Object not as expected" )
4451 return main.FALSE
4452 except pexpect.EOF:
4453 main.log.error( self.name + ": EOF exception found" )
4454 main.log.error( self.name + ": " + self.handle.before )
4455 main.cleanup()
4456 main.exit()
4457 except Exception:
4458 main.log.exception( self.name + ": Uncaught exception!" )
4459 main.cleanup()
4460 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004461
4462 def removeDevice( self, device ):
4463 '''
4464 Description:
4465 Remove a device from ONOS by passing the uri of the device(s).
4466 Parameters:
4467 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4468 Returns:
4469 Returns main.FALSE if an exception is thrown or an error is present
4470 in the response. Otherwise, returns main.TRUE.
4471 NOTE:
4472 If a host cannot be removed, then this function will return main.FALSE
4473 '''
4474 try:
4475 if type( device ) is str:
4476 device = list( device )
4477
4478 for d in device:
4479 time.sleep( 1 )
4480 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004481 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004482 if "Error" in response:
4483 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4484 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004485 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004486 except AssertionError:
4487 main.log.exception( "" )
4488 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004489 except TypeError:
4490 main.log.exception( self.name + ": Object not as expected" )
4491 return main.FALSE
4492 except pexpect.EOF:
4493 main.log.error( self.name + ": EOF exception found" )
4494 main.log.error( self.name + ": " + self.handle.before )
4495 main.cleanup()
4496 main.exit()
4497 except Exception:
4498 main.log.exception( self.name + ": Uncaught exception!" )
4499 main.cleanup()
4500 main.exit()
4501
4502 def removeHost( self, host ):
4503 '''
4504 Description:
4505 Remove a host from ONOS by passing the id of the host(s)
4506 Parameters:
4507 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4508 Returns:
4509 Returns main.FALSE if an exception is thrown or an error is present
4510 in the response. Otherwise, returns main.TRUE.
4511 NOTE:
4512 If a host cannot be removed, then this function will return main.FALSE
4513 '''
4514 try:
4515 if type( host ) is str:
4516 host = list( host )
4517
4518 for h in host:
4519 time.sleep( 1 )
4520 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004521 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004522 if "Error" in response:
4523 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4524 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004525 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004526 except AssertionError:
4527 main.log.exception( "" )
4528 return None
GlennRC20fc6522015-12-23 23:26:57 -08004529 except TypeError:
4530 main.log.exception( self.name + ": Object not as expected" )
4531 return main.FALSE
4532 except pexpect.EOF:
4533 main.log.error( self.name + ": EOF exception found" )
4534 main.log.error( self.name + ": " + self.handle.before )
4535 main.cleanup()
4536 main.exit()
4537 except Exception:
4538 main.log.exception( self.name + ": Uncaught exception!" )
4539 main.cleanup()
4540 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004541
Jon Hallc6793552016-01-19 14:18:37 -08004542 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004543 '''
4544 Description:
4545 Bring link down or up in the null-provider.
4546 params:
4547 begin - (string) One end of a device or switch.
4548 end - (string) the other end of the device or switch
4549 returns:
4550 main.TRUE if no exceptions were thrown and no Errors are
4551 present in the resoponse. Otherwise, returns main.FALSE
4552 '''
4553 try:
Jon Hallc6793552016-01-19 14:18:37 -08004554 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004555 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004556 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004557 if "Error" in response or "Failure" in response:
4558 main.log.error( response )
4559 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004560 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004561 except AssertionError:
4562 main.log.exception( "" )
4563 return None
GlennRCed771242016-01-13 17:02:47 -08004564 except TypeError:
4565 main.log.exception( self.name + ": Object not as expected" )
4566 return main.FALSE
4567 except pexpect.EOF:
4568 main.log.error( self.name + ": EOF exception found" )
4569 main.log.error( self.name + ": " + self.handle.before )
4570 main.cleanup()
4571 main.exit()
4572 except Exception:
4573 main.log.exception( self.name + ": Uncaught exception!" )
4574 main.cleanup()
4575 main.exit()
4576