blob: 082287978451451f56b1deb6fa9dd85b878ed996 [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
suibin zhang116647a2016-05-06 16:30:09 -0700304 def startCellCli( self, karafTimeout="",
305 commandlineTimeout=10, onosStartTimeout=60 ):
306 """
307 Start CLI on onos ecll handle.
308
309 karafTimeout is an optional argument. karafTimeout value passed
310 by user would be used to set the current karaf shell idle timeout.
311 Note that when ever this property is modified the shell will exit and
312 the subsequent login would reflect new idle timeout.
313 Below is an example to start a session with 60 seconds idle timeout
314 ( input value is in milliseconds ):
315
316 tValue = "60000"
317
318 Note: karafTimeout is left as str so that this could be read
319 and passed to startOnosCli from PARAMS file as str.
320 """
321
322 try:
323 self.handle.sendline( "" )
324 x = self.handle.expect( [
325 "\$", "onos>" ], commandlineTimeout)
326
327 if x == 1:
328 main.log.info( "ONOS cli is already running" )
329 return main.TRUE
330
331 # Wait for onos start ( -w ) and enter onos cli
332 self.handle.sendline( "/opt/onos/bin/onos" )
333 i = self.handle.expect( [
334 "onos>",
335 pexpect.TIMEOUT ], onosStartTimeout )
336
337 if i == 0:
338 main.log.info( self.name + " CLI Started successfully" )
339 if karafTimeout:
340 self.handle.sendline(
341 "config:property-set -p org.apache.karaf.shell\
342 sshIdleTimeout " +
343 karafTimeout )
344 self.handle.expect( "\$" )
345 self.handle.sendline( "/opt/onos/bin/onos" )
346 self.handle.expect( "onos>" )
347 return main.TRUE
348 else:
349 # If failed, send ctrl+c to process and try again
350 main.log.info( "Starting CLI failed. Retrying..." )
351 self.handle.send( "\x03" )
352 self.handle.sendline( "/opt/onos/bin/onos" )
353 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
354 timeout=30 )
355 if i == 0:
356 main.log.info( self.name + " CLI Started " +
357 "successfully after retry attempt" )
358 if karafTimeout:
359 self.handle.sendline(
360 "config:property-set -p org.apache.karaf.shell\
361 sshIdleTimeout " +
362 karafTimeout )
363 self.handle.expect( "\$" )
364 self.handle.sendline( "/opt/onos/bin/onos" )
365 self.handle.expect( "onos>" )
366 return main.TRUE
367 else:
368 main.log.error( "Connection to CLI " +
369 self.name + " timeout" )
370 return main.FALSE
371
372 except TypeError:
373 main.log.exception( self.name + ": Object not as expected" )
374 return None
375 except pexpect.EOF:
376 main.log.error( self.name + ": EOF exception found" )
377 main.log.error( self.name + ": " + self.handle.before )
378 main.cleanup()
379 main.exit()
380 except Exception:
381 main.log.exception( self.name + ": Uncaught exception!" )
382 main.cleanup()
383 main.exit()
384
YPZhangebf9eb52016-05-12 15:20:24 -0700385 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800386 """
387 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800388 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800389 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700390 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800391 Available level: DEBUG, TRACE, INFO, WARN, ERROR
392 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800393 """
394 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800395 lvlStr = ""
396 if level:
397 lvlStr = "--level=" + level
398
kelvin-onlab9f541032015-02-04 16:19:53 -0800399 self.handle.sendline( "" )
Jon Hallc6793552016-01-19 14:18:37 -0800400 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
Jon Hall80daded2015-05-27 16:07:00 -0700401 if i == 1:
You Wangf69ab392016-01-26 16:34:38 -0800402 main.log.error( self.name + ": onos cli session closed. ")
403 if self.onosIp:
404 main.log.warn( "Trying to reconnect " + self.onosIp )
405 reconnectResult = self.startOnosCli( self.onosIp )
406 if reconnectResult:
407 main.log.info( self.name + ": onos cli session reconnected." )
408 else:
409 main.log.error( self.name + ": reconnection failed." )
410 main.cleanup()
411 main.exit()
412 else:
413 main.cleanup()
414 main.exit()
Jon Hallc9eabec2015-06-10 14:33:14 -0700415 if i == 2:
Jon Hall80daded2015-05-27 16:07:00 -0700416 self.handle.sendline( "" )
417 self.handle.expect( "onos>" )
kelvin-onlab338f5512015-02-06 10:53:16 -0800418 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700419 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800420 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800421
kelvin-onlab9f541032015-02-04 16:19:53 -0800422 response = self.handle.before
423 if re.search( "Error", response ):
424 return main.FALSE
425 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700426 except pexpect.TIMEOUT:
427 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700428 if noExit:
429 main.cleanup()
430 return None
431 else:
432 main.cleanup()
433 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 except pexpect.EOF:
435 main.log.error( self.name + ": EOF exception found" )
436 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700437 if noExit:
438 main.cleanup()
439 return None
440 else:
441 main.cleanup()
442 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800443 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800444 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700445 if noExit:
446 main.cleanup()
447 return None
448 else:
449 main.cleanup()
450 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400451
YPZhangebf9eb52016-05-12 15:20:24 -0700452 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800453 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800454 Send a completely user specified string to
455 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400456 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800457
YPZhangebf9eb52016-05-12 15:20:24 -0700458 if noExit is True, TestON will not exit, but clean up
459
andrewonlaba18f6bf2014-10-13 19:31:54 -0400460 Warning: There are no sanity checking to commands
461 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800462
kelvin8ec71442015-01-15 16:57:00 -0800463 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400464 try:
Jon Hall14a03b52016-05-11 12:07:30 -0700465 if debug:
466 # NOTE: This adds and average of .4 seconds per call
467 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700468 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800469 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800470 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800471 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800472 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800473 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
474 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700475 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700476 main.log.debug( self.name + ": Raw output" )
477 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700478
479 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800480 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800481 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700482 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700483 main.log.debug( self.name + ": ansiEscape output" )
484 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700485
kelvin-onlabfb521662015-02-27 09:52:40 -0800486 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800487 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700488 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700489 main.log.debug( self.name + ": Removed extra returns " +
490 "from output" )
491 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700492
493 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800494 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700495 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700496 main.log.debug( self.name + ": parsed and stripped output" )
497 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498
Jon Hall63604932015-02-26 17:09:50 -0800499 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 output = response.split( cmdStr.strip(), 1 )
501 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700502 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700503 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700504 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800505 output = output[1].strip()
506 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800507 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800508 return output
GlennRCed771242016-01-13 17:02:47 -0800509 except pexpect.TIMEOUT:
510 main.log.error( self.name + ":ONOS timeout" )
511 if debug:
512 main.log.debug( self.handle.before )
513 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 except IndexError:
515 main.log.exception( self.name + ": Object not as expected" )
516 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800517 except TypeError:
518 main.log.exception( self.name + ": Object not as expected" )
519 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400520 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800521 main.log.error( self.name + ": EOF exception found" )
522 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700523 if noExit:
524 main.cleanup()
525 return None
526 else:
527 main.cleanup()
528 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800529 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800530 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700531 if noExit:
532 main.cleanup()
533 return None
534 else:
535 main.cleanup()
536 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400537
kelvin8ec71442015-01-15 16:57:00 -0800538 # IMPORTANT NOTE:
539 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800540 # the cli command changing 'a:b' with 'aB'.
541 # Ex ) onos:topology > onosTopology
542 # onos:links > onosLinks
543 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800544
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800546 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400547 Adds a new cluster node by ID and address information.
548 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800549 * nodeId
550 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400551 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800552 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800553 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400554 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800555 cmdStr = "add-node " + str( nodeId ) + " " +\
556 str( ONOSIp ) + " " + str( tcpPort )
557 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800558 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800559 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800560 main.log.error( "Error in adding node" )
561 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800562 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400563 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800564 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400565 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800566 except AssertionError:
567 main.log.exception( "" )
568 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800569 except TypeError:
570 main.log.exception( self.name + ": Object not as expected" )
571 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400572 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800573 main.log.error( self.name + ": EOF exception found" )
574 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400575 main.cleanup()
576 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800577 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800578 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 main.cleanup()
580 main.exit()
581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlab86dc3082014-10-13 18:18:38 -0400584 Removes a cluster by ID
585 Issues command: 'remove-node [<node-id>]'
586 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800588 """
andrewonlab86dc3082014-10-13 18:18:38 -0400589 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400590
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700592 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800593 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700594 if re.search( "Error", handle ):
595 main.log.error( "Error in removing node" )
596 main.log.error( handle )
597 return main.FALSE
598 else:
599 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800600 except AssertionError:
601 main.log.exception( "" )
602 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800603 except TypeError:
604 main.log.exception( self.name + ": Object not as expected" )
605 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800607 main.log.error( self.name + ": EOF exception found" )
608 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400609 main.cleanup()
610 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800611 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800612 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400613 main.cleanup()
614 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400615
Jon Hall61282e32015-03-19 11:34:11 -0700616 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800617 """
andrewonlab7c211572014-10-15 16:45:20 -0400618 List the nodes currently visible
619 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700620 Optional argument:
621 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800622 """
andrewonlab7c211572014-10-15 16:45:20 -0400623 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700624 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700625 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700626 cmdStr += " -j"
627 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800628 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700629 return output
Jon Hallc6793552016-01-19 14:18:37 -0800630 except AssertionError:
631 main.log.exception( "" )
632 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800633 except TypeError:
634 main.log.exception( self.name + ": Object not as expected" )
635 return None
andrewonlab7c211572014-10-15 16:45:20 -0400636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400639 main.cleanup()
640 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800641 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800642 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400643 main.cleanup()
644 main.exit()
645
kelvin8ec71442015-01-15 16:57:00 -0800646 def topology( self ):
647 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700648 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700649 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700650 Return:
651 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab95ce8322014-10-13 14:12:04 -0400653 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700654 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800656 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700657 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400658 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800659 except AssertionError:
660 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800661 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800662 except TypeError:
663 main.log.exception( self.name + ": Object not as expected" )
664 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400665 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800666 main.log.error( self.name + ": EOF exception found" )
667 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400668 main.cleanup()
669 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800670 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800671 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400672 main.cleanup()
673 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800674
jenkins7ead5a82015-03-13 10:28:21 -0700675 def deviceRemove( self, deviceId ):
676 """
677 Removes particular device from storage
678
679 TODO: refactor this function
680 """
681 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700682 cmdStr = "device-remove " + str( deviceId )
683 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800684 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700685 if re.search( "Error", handle ):
686 main.log.error( "Error in removing device" )
687 main.log.error( handle )
688 return main.FALSE
689 else:
690 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800691 except AssertionError:
692 main.log.exception( "" )
693 return None
jenkins7ead5a82015-03-13 10:28:21 -0700694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
697 except pexpect.EOF:
698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
700 main.cleanup()
701 main.exit()
702 except Exception:
703 main.log.exception( self.name + ": Uncaught exception!" )
704 main.cleanup()
705 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700706
kelvin-onlabd3b64892015-01-20 13:26:24 -0800707 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800708 """
Jon Hall7b02d952014-10-17 20:14:54 -0400709 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400710 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800712 """
andrewonlab86dc3082014-10-13 18:18:38 -0400713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800715 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700716 cmdStr += " -j"
717 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800720 except AssertionError:
721 main.log.exception( "" )
722 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800723 except TypeError:
724 main.log.exception( self.name + ": Object not as expected" )
725 return None
andrewonlab7c211572014-10-15 16:45:20 -0400726 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800727 main.log.error( self.name + ": EOF exception found" )
728 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400729 main.cleanup()
730 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800731 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800732 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400733 main.cleanup()
734 main.exit()
735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800737 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800738 This balances the devices across all controllers
739 by issuing command: 'onos> onos:balance-masters'
740 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800742 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700744 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800745 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 if re.search( "Error", handle ):
747 main.log.error( "Error in balancing masters" )
748 main.log.error( handle )
749 return main.FALSE
750 else:
751 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800761 main.cleanup()
762 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800765 main.cleanup()
766 main.exit()
767
Jon Hallc6793552016-01-19 14:18:37 -0800768 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700769 """
770 Returns the output of the masters command.
771 Optional argument:
772 * jsonFormat - boolean indicating if you want output in json
773 """
774 try:
775 cmdStr = "onos:masters"
776 if jsonFormat:
777 cmdStr += " -j"
778 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800779 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700780 return output
Jon Hallc6793552016-01-19 14:18:37 -0800781 except AssertionError:
782 main.log.exception( "" )
783 return None
acsmars24950022015-07-30 18:00:43 -0700784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
787 except pexpect.EOF:
788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
790 main.cleanup()
791 main.exit()
792 except Exception:
793 main.log.exception( self.name + ": Uncaught exception!" )
794 main.cleanup()
795 main.exit()
796
Jon Hallc6793552016-01-19 14:18:37 -0800797 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Uses the master command to check that the devices' leadership
800 is evenly divided
801
802 Dependencies: checkMasters() and summary()
803
804 Returns main.True if the devices are balanced
805 Returns main.False if the devices are unbalanced
806 Exits on Exception
807 Returns None on TypeError
808 """
809 try:
Jon Hallc6793552016-01-19 14:18:37 -0800810 summaryOutput = self.summary()
811 totalDevices = json.loads( summaryOutput )[ "devices" ]
812 except ( TypeError, ValueError ):
813 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
814 return None
815 try:
acsmars24950022015-07-30 18:00:43 -0700816 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800817 mastersOutput = self.checkMasters()
818 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700819 first = masters[ 0 ][ "size" ]
820 for master in masters:
821 totalOwnedDevices += master[ "size" ]
822 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
823 main.log.error( "Mastership not balanced" )
824 main.log.info( "\n" + self.checkMasters( False ) )
825 return main.FALSE
826 main.log.info( "Mastership balanced between " \
827 + str( len(masters) ) + " masters" )
828 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800829 except ( TypeError, ValueError ):
830 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700831 return None
832 except pexpect.EOF:
833 main.log.error( self.name + ": EOF exception found" )
834 main.log.error( self.name + ": " + self.handle.before )
835 main.cleanup()
836 main.exit()
837 except Exception:
838 main.log.exception( self.name + ": Uncaught exception!" )
839 main.cleanup()
840 main.exit()
841
kelvin-onlabd3b64892015-01-20 13:26:24 -0800842 def links( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800843 """
Jon Halle8217482014-10-17 13:49:14 -0400844 Lists all core links
845 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800846 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800847 """
Jon Halle8217482014-10-17 13:49:14 -0400848 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700849 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800850 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700851 cmdStr += " -j"
852 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800853 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700854 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800855 except AssertionError:
856 main.log.exception( "" )
857 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800858 except TypeError:
859 main.log.exception( self.name + ": Object not as expected" )
860 return None
Jon Halle8217482014-10-17 13:49:14 -0400861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400864 main.cleanup()
865 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800867 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400868 main.cleanup()
869 main.exit()
870
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800872 """
Jon Halle8217482014-10-17 13:49:14 -0400873 Lists all ports
874 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800875 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800876 """
Jon Halle8217482014-10-17 13:49:14 -0400877 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800879 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700880 cmdStr += " -j"
881 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800882 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700883 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800884 except AssertionError:
885 main.log.exception( "" )
886 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800887 except TypeError:
888 main.log.exception( self.name + ": Object not as expected" )
889 return None
Jon Halle8217482014-10-17 13:49:14 -0400890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800891 main.log.error( self.name + ": EOF exception found" )
892 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400893 main.cleanup()
894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400897 main.cleanup()
898 main.exit()
899
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Hall983a1702014-10-28 18:44:22 -0400902 Lists all devices and the controllers with roles assigned to them
903 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800905 """
andrewonlab7c211572014-10-15 16:45:20 -0400906 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700907 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr += " -j"
910 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800911 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700912 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800913 except AssertionError:
914 main.log.exception( "" )
915 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800916 except TypeError:
917 main.log.exception( self.name + ": Object not as expected" )
918 return None
Jon Hall983a1702014-10-28 18:44:22 -0400919 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800920 main.log.error( self.name + ": EOF exception found" )
921 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400922 main.cleanup()
923 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800924 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800925 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400926 main.cleanup()
927 main.exit()
928
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800930 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800931 Given the a string containing the json representation of the "roles"
932 cli command and a partial or whole device id, returns a json object
933 containing the roles output for the first device whose id contains
934 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400935
936 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800937 A dict of the role assignments for the given device or
938 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Hall983a1702014-10-28 18:44:22 -0400940 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400942 return None
943 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800944 rawRoles = self.roles()
945 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800946 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800947 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800948 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800949 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400950 return device
951 return None
Jon Hallc6793552016-01-19 14:18:37 -0800952 except ( TypeError, ValueError ):
953 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800954 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400958 main.cleanup()
959 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800961 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400962 main.cleanup()
963 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800966 """
Jon Hall94fd0472014-12-08 11:52:42 -0800967 Iterates through each device and checks if there is a master assigned
968 Returns: main.TRUE if each device has a master
969 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800970 """
Jon Hall94fd0472014-12-08 11:52:42 -0800971 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 rawRoles = self.roles()
973 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800974 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800975 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800976 # print device
977 if device[ 'master' ] == "none":
978 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800979 return main.FALSE
980 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800981 except ( TypeError, ValueError ):
982 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800983 return None
Jon Hall94fd0472014-12-08 11:52:42 -0800984 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800985 main.log.error( self.name + ": EOF exception found" )
986 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -0800987 main.cleanup()
988 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800989 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800990 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800991 main.cleanup()
992 main.exit()
993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -0800995 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400996 Returns string of paths, and the cost.
997 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -0800998 """
andrewonlab3e15ead2014-10-15 14:21:34 -0400999 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001000 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1001 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001002 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001003 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001004 main.log.error( "Error in getting paths" )
1005 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001006 else:
kelvin8ec71442015-01-15 16:57:00 -08001007 path = handle.split( ";" )[ 0 ]
1008 cost = handle.split( ";" )[ 1 ]
1009 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001010 except AssertionError:
1011 main.log.exception( "" )
1012 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001013 except TypeError:
1014 main.log.exception( self.name + ": Object not as expected" )
1015 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001017 main.log.error( self.name + ": EOF exception found" )
1018 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 main.cleanup()
1020 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001021 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001022 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001023 main.cleanup()
1024 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001025
kelvin-onlabd3b64892015-01-20 13:26:24 -08001026 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001027 """
Jon Hallffb386d2014-11-21 13:43:38 -08001028 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001029 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001030 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001031 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001032 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001033 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001035 cmdStr += " -j"
1036 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001037 if handle:
1038 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001039 # TODO: Maybe make this less hardcoded
1040 # ConsistentMap Exceptions
1041 assert "org.onosproject.store.service" not in handle
1042 # Node not leader
1043 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001044 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001045 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001046 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001047 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001048 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001049 except TypeError:
1050 main.log.exception( self.name + ": Object not as expected" )
1051 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001052 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001053 main.log.error( self.name + ": EOF exception found" )
1054 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001055 main.cleanup()
1056 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001057 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001058 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001059 main.cleanup()
1060 main.exit()
1061
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001063 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001064 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001065
Jon Hallefbd9792015-03-05 16:11:36 -08001066 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001067 partial mac address
1068
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001070 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 try:
kelvin8ec71442015-01-15 16:57:00 -08001072 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001073 return None
1074 else:
1075 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001076 rawHosts = self.hosts()
1077 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001078 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001080 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001081 if not host:
1082 pass
1083 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001084 return host
1085 return None
Jon Hallc6793552016-01-19 14:18:37 -08001086 except ( TypeError, ValueError ):
1087 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001088 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001090 main.log.error( self.name + ": EOF exception found" )
1091 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 main.cleanup()
1093 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001094 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001095 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001096 main.cleanup()
1097 main.exit()
1098
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001100 """
1101 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001102 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001103
andrewonlab3f0a4af2014-10-17 12:25:14 -04001104 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001105 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001106 IMPORTANT:
1107 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001108 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001109 Furthermore, it assumes that value of VLAN is '-1'
1110 Description:
kelvin8ec71442015-01-15 16:57:00 -08001111 Converts mininet hosts ( h1, h2, h3... ) into
1112 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1113 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001114 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001118 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 hostHex = hex( int( host ) ).zfill( 12 )
1120 hostHex = str( hostHex ).replace( 'x', '0' )
1121 i = iter( str( hostHex ) )
1122 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1123 hostHex = hostHex + "/-1"
1124 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001125
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001127
Jon Halld4d4b372015-01-28 16:02:41 -08001128 except TypeError:
1129 main.log.exception( self.name + ": Object not as expected" )
1130 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001132 main.log.error( self.name + ": EOF exception found" )
1133 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001134 main.cleanup()
1135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001137 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 main.cleanup()
1139 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001140
Jeremy Songster832f9e92016-05-05 14:30:49 -07001141 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001142 """
andrewonlabe6745342014-10-17 14:29:13 -04001143 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 * hostIdOne: ONOS host id for host1
1145 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001146 Optional:
1147 * vlanId: specify a VLAN id for the intent
andrewonlabe6745342014-10-17 14:29:13 -04001148 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001149 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001150 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001151 Returns:
1152 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001153 """
andrewonlabe6745342014-10-17 14:29:13 -04001154 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001155 cmdStr = "add-host-intent "
1156 if vlanId:
1157 cmdStr += "-v " + str( vlanId ) + " "
1158 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001160 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001161 if re.search( "Error", handle ):
1162 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001163 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001164 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001165 else:
1166 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001167 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1168 match = re.search('id=0x([\da-f]+),', handle)
1169 if match:
1170 return match.group()[3:-1]
1171 else:
1172 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001173 main.log.debug( "Response from ONOS was: " +
1174 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001175 return None
Jon Hallc6793552016-01-19 14:18:37 -08001176 except AssertionError:
1177 main.log.exception( "" )
1178 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001179 except TypeError:
1180 main.log.exception( self.name + ": Object not as expected" )
1181 return None
andrewonlabe6745342014-10-17 14:29:13 -04001182 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001183 main.log.error( self.name + ": EOF exception found" )
1184 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001185 main.cleanup()
1186 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001189 main.cleanup()
1190 main.exit()
1191
kelvin-onlabd3b64892015-01-20 13:26:24 -08001192 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001193 """
andrewonlab7b31d232014-10-24 13:31:47 -04001194 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001195 * ingressDevice: device id of ingress device
1196 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001197 Optional:
1198 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001199 Description:
1200 Adds an optical intent by specifying an ingress and egress device
1201 Returns:
1202 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001203 """
andrewonlab7b31d232014-10-24 13:31:47 -04001204 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1206 " " + str( egressDevice )
1207 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001208 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001209 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001210 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001211 main.log.error( "Error in adding Optical intent" )
1212 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001213 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001214 main.log.info( "Optical intent installed between " +
1215 str( ingressDevice ) + " and " +
1216 str( egressDevice ) )
1217 match = re.search('id=0x([\da-f]+),', handle)
1218 if match:
1219 return match.group()[3:-1]
1220 else:
1221 main.log.error( "Error, intent ID not found" )
1222 return None
Jon Hallc6793552016-01-19 14:18:37 -08001223 except AssertionError:
1224 main.log.exception( "" )
1225 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001226 except TypeError:
1227 main.log.exception( self.name + ": Object not as expected" )
1228 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001229 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001230 main.log.error( self.name + ": EOF exception found" )
1231 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001232 main.cleanup()
1233 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001234 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001235 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001236 main.cleanup()
1237 main.exit()
1238
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001240 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 ingressDevice,
1242 egressDevice,
1243 portIngress="",
1244 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001245 ethType="",
1246 ethSrc="",
1247 ethDst="",
1248 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001249 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001250 ipProto="",
1251 ipSrc="",
1252 ipDst="",
1253 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001254 tcpDst="",
1255 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001256 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001257 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 * ingressDevice: device id of ingress device
1259 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001260 Optional:
1261 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001262 * ethSrc: specify ethSrc ( i.e. src mac addr )
1263 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001264 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001265 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001266 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001267 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001268 * ipSrc: specify ip source address
1269 * ipDst: specify ip destination address
1270 * tcpSrc: specify tcp source port
1271 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001272 * vlanId: specify vlan ID
andrewonlab4dbb4d82014-10-17 18:22:31 -04001273 Description:
kelvin8ec71442015-01-15 16:57:00 -08001274 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001275 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001276 Returns:
1277 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001278
Jon Halle3f39ff2015-01-13 11:50:53 -08001279 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001280 options developers provide for point-to-point
1281 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001282 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001283 try:
kelvin8ec71442015-01-15 16:57:00 -08001284 # If there are no optional arguments
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 and not bandwidth and not lambdaAlloc \
andrewonlabfa4ff502014-11-11 16:41:30 -05001287 and not ipProto and not ipSrc and not ipDst \
1288 and not tcpSrc and not tcpDst:
andrewonlab36af3822014-11-18 17:48:18 -05001289 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001290
andrewonlab289e4b72014-10-21 21:24:18 -04001291 else:
andrewonlab36af3822014-11-18 17:48:18 -05001292 cmd = "add-point-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001293
andrewonlab0c0a6772014-10-22 12:31:18 -04001294 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001295 cmd += " --ethType " + str( ethType )
andrewonlab289e4b72014-10-21 21:24:18 -04001296 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001297 cmd += " --ethSrc " + str( ethSrc )
1298 if ethDst:
1299 cmd += " --ethDst " + str( ethDst )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001300 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001301 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001302 if lambdaAlloc:
andrewonlabfa4ff502014-11-11 16:41:30 -05001303 cmd += " --lambda "
1304 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001305 cmd += " --ipProto " + str( ipProto )
andrewonlabfa4ff502014-11-11 16:41:30 -05001306 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001307 cmd += " --ipSrc " + str( ipSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001308 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001309 cmd += " --ipDst " + str( ipDst )
andrewonlabfa4ff502014-11-11 16:41:30 -05001310 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001311 cmd += " --tcpSrc " + str( tcpSrc )
andrewonlabfa4ff502014-11-11 16:41:30 -05001312 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001313 cmd += " --tcpDst " + str( tcpDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001314 if vlanId:
1315 cmd += " -v " + str( vlanId )
andrewonlab289e4b72014-10-21 21:24:18 -04001316
kelvin8ec71442015-01-15 16:57:00 -08001317 # Check whether the user appended the port
1318 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001319 if "/" in ingressDevice:
1320 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001321 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001323 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001324 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001325 # Would it make sense to throw an exception and exit
1326 # the test?
1327 return None
andrewonlab36af3822014-11-18 17:48:18 -05001328
kelvin8ec71442015-01-15 16:57:00 -08001329 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001330 str( ingressDevice ) + "/" +\
1331 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001332
kelvin-onlabd3b64892015-01-20 13:26:24 -08001333 if "/" in egressDevice:
1334 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001335 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001337 main.log.error( "You must specify the egress port" )
1338 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001339
kelvin8ec71442015-01-15 16:57:00 -08001340 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 str( egressDevice ) + "/" +\
1342 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001343
kelvin-onlab898a6c62015-01-16 14:13:53 -08001344 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001345 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001347 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001348 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001350 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001351 # TODO: print out all the options in this message?
1352 main.log.info( "Point-to-point intent installed between " +
1353 str( ingressDevice ) + " and " +
1354 str( egressDevice ) )
1355 match = re.search('id=0x([\da-f]+),', handle)
1356 if match:
1357 return match.group()[3:-1]
1358 else:
1359 main.log.error( "Error, intent ID not found" )
1360 return None
Jon Hallc6793552016-01-19 14:18:37 -08001361 except AssertionError:
1362 main.log.exception( "" )
1363 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001364 except TypeError:
1365 main.log.exception( self.name + ": Object not as expected" )
1366 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001367 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001368 main.log.error( self.name + ": EOF exception found" )
1369 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001370 main.cleanup()
1371 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001372 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001373 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001374 main.cleanup()
1375 main.exit()
1376
kelvin-onlabd3b64892015-01-20 13:26:24 -08001377 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001378 self,
shahshreyac2f97072015-03-19 17:04:29 -07001379 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001381 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001383 ethType="",
1384 ethSrc="",
1385 ethDst="",
1386 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001387 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001388 ipProto="",
1389 ipSrc="",
1390 ipDst="",
1391 tcpSrc="",
1392 tcpDst="",
1393 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001394 setEthDst="",
1395 vlanId="" ):
kelvin8ec71442015-01-15 16:57:00 -08001396 """
shahshreyad0c80432014-12-04 16:56:05 -08001397 Note:
shahshreya70622b12015-03-19 17:19:00 -07001398 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001399 is same. That is, all ingress devices include port numbers
1400 with a "/" or all ingress devices could specify device
1401 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001402 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001403 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001404 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001405 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001406 Optional:
1407 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001408 * ethSrc: specify ethSrc ( i.e. src mac addr )
1409 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001410 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001412 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001413 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001414 * ipSrc: specify ip source address
1415 * ipDst: specify ip destination address
1416 * tcpSrc: specify tcp source port
1417 * tcpDst: specify tcp destination port
1418 * setEthSrc: action to Rewrite Source MAC Address
1419 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001420 * vlanId: specify vlan Id
shahshreyad0c80432014-12-04 16:56:05 -08001421 Description:
kelvin8ec71442015-01-15 16:57:00 -08001422 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001423 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001424 Returns:
1425 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001426
Jon Halle3f39ff2015-01-13 11:50:53 -08001427 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001428 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001429 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001430 """
shahshreyad0c80432014-12-04 16:56:05 -08001431 try:
kelvin8ec71442015-01-15 16:57:00 -08001432 # If there are no optional arguments
shahshreyad0c80432014-12-04 16:56:05 -08001433 if not ethType and not ethSrc and not ethDst\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 and not bandwidth and not lambdaAlloc\
Jon Halle3f39ff2015-01-13 11:50:53 -08001435 and not ipProto and not ipSrc and not ipDst\
1436 and not tcpSrc and not tcpDst and not setEthSrc\
1437 and not setEthDst:
shahshreyad0c80432014-12-04 16:56:05 -08001438 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001439
1440 else:
1441 cmd = "add-multi-to-single-intent"
Jon Halle3f39ff2015-01-13 11:50:53 -08001442
shahshreyad0c80432014-12-04 16:56:05 -08001443 if ethType:
kelvin8ec71442015-01-15 16:57:00 -08001444 cmd += " --ethType " + str( ethType )
shahshreyad0c80432014-12-04 16:56:05 -08001445 if ethSrc:
kelvin8ec71442015-01-15 16:57:00 -08001446 cmd += " --ethSrc " + str( ethSrc )
1447 if ethDst:
1448 cmd += " --ethDst " + str( ethDst )
shahshreyad0c80432014-12-04 16:56:05 -08001449 if bandwidth:
kelvin8ec71442015-01-15 16:57:00 -08001450 cmd += " --bandwidth " + str( bandwidth )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001451 if lambdaAlloc:
shahshreyad0c80432014-12-04 16:56:05 -08001452 cmd += " --lambda "
1453 if ipProto:
kelvin8ec71442015-01-15 16:57:00 -08001454 cmd += " --ipProto " + str( ipProto )
shahshreyad0c80432014-12-04 16:56:05 -08001455 if ipSrc:
kelvin8ec71442015-01-15 16:57:00 -08001456 cmd += " --ipSrc " + str( ipSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001457 if ipDst:
kelvin8ec71442015-01-15 16:57:00 -08001458 cmd += " --ipDst " + str( ipDst )
shahshreyad0c80432014-12-04 16:56:05 -08001459 if tcpSrc:
kelvin8ec71442015-01-15 16:57:00 -08001460 cmd += " --tcpSrc " + str( tcpSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001461 if tcpDst:
kelvin8ec71442015-01-15 16:57:00 -08001462 cmd += " --tcpDst " + str( tcpDst )
shahshreyad0c80432014-12-04 16:56:05 -08001463 if setEthSrc:
kelvin8ec71442015-01-15 16:57:00 -08001464 cmd += " --setEthSrc " + str( setEthSrc )
shahshreyad0c80432014-12-04 16:56:05 -08001465 if setEthDst:
kelvin8ec71442015-01-15 16:57:00 -08001466 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001467 if vlanId:
1468 cmd += " -v " + str( vlanId )
shahshreyad0c80432014-12-04 16:56:05 -08001469
kelvin8ec71442015-01-15 16:57:00 -08001470 # Check whether the user appended the port
1471 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001472
1473 if portIngressList is None:
1474 for ingressDevice in ingressDeviceList:
1475 if "/" in ingressDevice:
1476 cmd += " " + str( ingressDevice )
1477 else:
1478 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001479 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001480 # TODO: perhaps more meaningful return
1481 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001482 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001483 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001484 for ingressDevice, portIngress in zip( ingressDeviceList,
1485 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001486 cmd += " " + \
1487 str( ingressDevice ) + "/" +\
1488 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001489 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001490 main.log.error( "Device list and port list does not " +
1491 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001492 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 if "/" in egressDevice:
1494 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001495 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001496 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001497 main.log.error( "You must specify " +
1498 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001499 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001500
kelvin8ec71442015-01-15 16:57:00 -08001501 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 str( egressDevice ) + "/" +\
1503 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001504 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001505 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001506 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001507 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001508 main.log.error( "Error in adding multipoint-to-singlepoint " +
1509 "intent" )
1510 return None
shahshreyad0c80432014-12-04 16:56:05 -08001511 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001512 match = re.search('id=0x([\da-f]+),', handle)
1513 if match:
1514 return match.group()[3:-1]
1515 else:
1516 main.log.error( "Error, intent ID not found" )
1517 return None
Jon Hallc6793552016-01-19 14:18:37 -08001518 except AssertionError:
1519 main.log.exception( "" )
1520 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001521 except TypeError:
1522 main.log.exception( self.name + ": Object not as expected" )
1523 return None
1524 except pexpect.EOF:
1525 main.log.error( self.name + ": EOF exception found" )
1526 main.log.error( self.name + ": " + self.handle.before )
1527 main.cleanup()
1528 main.exit()
1529 except Exception:
1530 main.log.exception( self.name + ": Uncaught exception!" )
1531 main.cleanup()
1532 main.exit()
1533
1534 def addSinglepointToMultipointIntent(
1535 self,
1536 ingressDevice,
1537 egressDeviceList,
1538 portIngress="",
1539 portEgressList=None,
1540 ethType="",
1541 ethSrc="",
1542 ethDst="",
1543 bandwidth="",
1544 lambdaAlloc=False,
1545 ipProto="",
1546 ipSrc="",
1547 ipDst="",
1548 tcpSrc="",
1549 tcpDst="",
1550 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001551 setEthDst="",
1552 vlanId="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001553 """
1554 Note:
1555 This function assumes the format of all egress devices
1556 is same. That is, all egress devices include port numbers
1557 with a "/" or all egress devices could specify device
1558 ids and port numbers seperately.
1559 Required:
1560 * EgressDeviceList: List of device ids of egress device
1561 ( Atleast 2 eress devices required in the list )
1562 * ingressDevice: device id of ingress device
1563 Optional:
1564 * ethType: specify ethType
1565 * ethSrc: specify ethSrc ( i.e. src mac addr )
1566 * ethDst: specify ethDst ( i.e. dst mac addr )
1567 * bandwidth: specify bandwidth capacity of link
1568 * lambdaAlloc: if True, intent will allocate lambda
1569 for the specified intent
1570 * ipProto: specify ip protocol
1571 * ipSrc: specify ip source address
1572 * ipDst: specify ip destination address
1573 * tcpSrc: specify tcp source port
1574 * tcpDst: specify tcp destination port
1575 * setEthSrc: action to Rewrite Source MAC Address
1576 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001577 * vlanId: specify vlan Id
kelvin-onlabb9408212015-04-01 13:34:04 -07001578 Description:
1579 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1580 specifying device id's and optional fields
1581 Returns:
1582 A string of the intent id or None on error
1583
1584 NOTE: This function may change depending on the
1585 options developers provide for singlepoint-to-multipoint
1586 intent via cli
1587 """
1588 try:
1589 # If there are no optional arguments
1590 if not ethType and not ethSrc and not ethDst\
1591 and not bandwidth and not lambdaAlloc\
1592 and not ipProto and not ipSrc and not ipDst\
1593 and not tcpSrc and not tcpDst and not setEthSrc\
1594 and not setEthDst:
1595 cmd = "add-single-to-multi-intent"
1596
1597 else:
1598 cmd = "add-single-to-multi-intent"
1599
1600 if ethType:
1601 cmd += " --ethType " + str( ethType )
1602 if ethSrc:
1603 cmd += " --ethSrc " + str( ethSrc )
1604 if ethDst:
1605 cmd += " --ethDst " + str( ethDst )
1606 if bandwidth:
1607 cmd += " --bandwidth " + str( bandwidth )
1608 if lambdaAlloc:
1609 cmd += " --lambda "
1610 if ipProto:
1611 cmd += " --ipProto " + str( ipProto )
1612 if ipSrc:
1613 cmd += " --ipSrc " + str( ipSrc )
1614 if ipDst:
1615 cmd += " --ipDst " + str( ipDst )
1616 if tcpSrc:
1617 cmd += " --tcpSrc " + str( tcpSrc )
1618 if tcpDst:
1619 cmd += " --tcpDst " + str( tcpDst )
1620 if setEthSrc:
1621 cmd += " --setEthSrc " + str( setEthSrc )
1622 if setEthDst:
1623 cmd += " --setEthDst " + str( setEthDst )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001624 if vlanId:
1625 cmd += " -v " + str( vlanId )
kelvin-onlabb9408212015-04-01 13:34:04 -07001626
1627 # Check whether the user appended the port
1628 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001629
kelvin-onlabb9408212015-04-01 13:34:04 -07001630 if "/" in ingressDevice:
1631 cmd += " " + str( ingressDevice )
1632 else:
1633 if not portIngress:
1634 main.log.error( "You must specify " +
1635 "the Ingress port" )
1636 return main.FALSE
1637
1638 cmd += " " +\
1639 str( ingressDevice ) + "/" +\
1640 str( portIngress )
1641
1642 if portEgressList is None:
1643 for egressDevice in egressDeviceList:
1644 if "/" in egressDevice:
1645 cmd += " " + str( egressDevice )
1646 else:
1647 main.log.error( "You must specify " +
1648 "the egress port" )
1649 # TODO: perhaps more meaningful return
1650 return main.FALSE
1651 else:
1652 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001653 for egressDevice, portEgress in zip( egressDeviceList,
1654 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001655 cmd += " " + \
1656 str( egressDevice ) + "/" +\
1657 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001658 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001659 main.log.error( "Device list and port list does not " +
1660 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001661 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001662 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001663 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001664 # If error, return error message
1665 if re.search( "Error", handle ):
1666 main.log.error( "Error in adding singlepoint-to-multipoint " +
1667 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001668 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001669 else:
1670 match = re.search('id=0x([\da-f]+),', handle)
1671 if match:
1672 return match.group()[3:-1]
1673 else:
1674 main.log.error( "Error, intent ID not found" )
1675 return None
Jon Hallc6793552016-01-19 14:18:37 -08001676 except AssertionError:
1677 main.log.exception( "" )
1678 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001679 except TypeError:
1680 main.log.exception( self.name + ": Object not as expected" )
1681 return None
shahshreyad0c80432014-12-04 16:56:05 -08001682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001683 main.log.error( self.name + ": EOF exception found" )
1684 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001685 main.cleanup()
1686 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001687 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001688 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001689 main.cleanup()
1690 main.exit()
1691
Hari Krishna9e232602015-04-13 17:29:08 -07001692 def addMplsIntent(
1693 self,
1694 ingressDevice,
1695 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001696 ingressPort="",
1697 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001698 ethType="",
1699 ethSrc="",
1700 ethDst="",
1701 bandwidth="",
1702 lambdaAlloc=False,
1703 ipProto="",
1704 ipSrc="",
1705 ipDst="",
1706 tcpSrc="",
1707 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001708 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001709 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001710 priority=""):
1711 """
1712 Required:
1713 * ingressDevice: device id of ingress device
1714 * egressDevice: device id of egress device
1715 Optional:
1716 * ethType: specify ethType
1717 * ethSrc: specify ethSrc ( i.e. src mac addr )
1718 * ethDst: specify ethDst ( i.e. dst mac addr )
1719 * bandwidth: specify bandwidth capacity of link
1720 * lambdaAlloc: if True, intent will allocate lambda
1721 for the specified intent
1722 * ipProto: specify ip protocol
1723 * ipSrc: specify ip source address
1724 * ipDst: specify ip destination address
1725 * tcpSrc: specify tcp source port
1726 * tcpDst: specify tcp destination port
1727 * ingressLabel: Ingress MPLS label
1728 * egressLabel: Egress MPLS label
1729 Description:
1730 Adds MPLS intent by
1731 specifying device id's and optional fields
1732 Returns:
1733 A string of the intent id or None on error
1734
1735 NOTE: This function may change depending on the
1736 options developers provide for MPLS
1737 intent via cli
1738 """
1739 try:
1740 # If there are no optional arguments
1741 if not ethType and not ethSrc and not ethDst\
1742 and not bandwidth and not lambdaAlloc \
1743 and not ipProto and not ipSrc and not ipDst \
1744 and not tcpSrc and not tcpDst and not ingressLabel \
1745 and not egressLabel:
1746 cmd = "add-mpls-intent"
1747
1748 else:
1749 cmd = "add-mpls-intent"
1750
1751 if ethType:
1752 cmd += " --ethType " + str( ethType )
1753 if ethSrc:
1754 cmd += " --ethSrc " + str( ethSrc )
1755 if ethDst:
1756 cmd += " --ethDst " + str( ethDst )
1757 if bandwidth:
1758 cmd += " --bandwidth " + str( bandwidth )
1759 if lambdaAlloc:
1760 cmd += " --lambda "
1761 if ipProto:
1762 cmd += " --ipProto " + str( ipProto )
1763 if ipSrc:
1764 cmd += " --ipSrc " + str( ipSrc )
1765 if ipDst:
1766 cmd += " --ipDst " + str( ipDst )
1767 if tcpSrc:
1768 cmd += " --tcpSrc " + str( tcpSrc )
1769 if tcpDst:
1770 cmd += " --tcpDst " + str( tcpDst )
1771 if ingressLabel:
1772 cmd += " --ingressLabel " + str( ingressLabel )
1773 if egressLabel:
1774 cmd += " --egressLabel " + str( egressLabel )
1775 if priority:
1776 cmd += " --priority " + str( priority )
1777
1778 # Check whether the user appended the port
1779 # or provided it as an input
1780 if "/" in ingressDevice:
1781 cmd += " " + str( ingressDevice )
1782 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001783 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001784 main.log.error( "You must specify the ingress port" )
1785 return None
1786
1787 cmd += " " + \
1788 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001789 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001790
1791 if "/" in egressDevice:
1792 cmd += " " + str( egressDevice )
1793 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001794 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001795 main.log.error( "You must specify the egress port" )
1796 return None
1797
1798 cmd += " " +\
1799 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001800 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001801
1802 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001803 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001804 # If error, return error message
1805 if re.search( "Error", handle ):
1806 main.log.error( "Error in adding mpls intent" )
1807 return None
1808 else:
1809 # TODO: print out all the options in this message?
1810 main.log.info( "MPLS intent installed between " +
1811 str( ingressDevice ) + " and " +
1812 str( egressDevice ) )
1813 match = re.search('id=0x([\da-f]+),', handle)
1814 if match:
1815 return match.group()[3:-1]
1816 else:
1817 main.log.error( "Error, intent ID not found" )
1818 return None
Jon Hallc6793552016-01-19 14:18:37 -08001819 except AssertionError:
1820 main.log.exception( "" )
1821 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001822 except TypeError:
1823 main.log.exception( self.name + ": Object not as expected" )
1824 return None
1825 except pexpect.EOF:
1826 main.log.error( self.name + ": EOF exception found" )
1827 main.log.error( self.name + ": " + self.handle.before )
1828 main.cleanup()
1829 main.exit()
1830 except Exception:
1831 main.log.exception( self.name + ": Uncaught exception!" )
1832 main.cleanup()
1833 main.exit()
1834
Jon Hallefbd9792015-03-05 16:11:36 -08001835 def removeIntent( self, intentId, app='org.onosproject.cli',
1836 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001837 """
shahshreya1c818fc2015-02-26 13:44:08 -08001838 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001839 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001840 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001841 -p or --purge: Purge the intent from the store after removal
1842
Jon Halle3f39ff2015-01-13 11:50:53 -08001843 Returns:
1844 main.False on error and
1845 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001846 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001847 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001848 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001849 if purge:
1850 cmdStr += " -p"
1851 if sync:
1852 cmdStr += " -s"
1853
1854 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001855 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001856 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001858 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001859 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001860 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001861 # TODO: Should this be main.TRUE
1862 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001863 except AssertionError:
1864 main.log.exception( "" )
1865 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001866 except TypeError:
1867 main.log.exception( self.name + ": Object not as expected" )
1868 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001869 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 main.cleanup()
1873 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001874 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001875 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001876 main.cleanup()
1877 main.exit()
1878
Jeremy42df2e72016-02-23 16:37:46 -08001879 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli' ):
1880 """
1881 Description:
1882 Remove all the intents
1883 Optional args:-
1884 -s or --sync: Waits for the removal before returning
1885 -p or --purge: Purge the intent from the store after removal
1886 Returns:
1887 Returns main.TRUE if all intents are removed, otherwise returns
1888 main.FALSE; Returns None for exception
1889 """
1890 try:
1891 cmdStr = "remove-intent"
1892 if purge:
1893 cmdStr += " -p"
1894 if sync:
1895 cmdStr += " -s"
1896
1897 cmdStr += " " + app
1898 handle = self.sendline( cmdStr )
1899 assert "Command not found:" not in handle, handle
1900 if re.search( "Error", handle ):
1901 main.log.error( "Error in removing intent" )
1902 return main.FALSE
1903 else:
1904 return main.TRUE
1905 except AssertionError:
1906 main.log.exception( "" )
1907 return None
1908 except TypeError:
1909 main.log.exception( self.name + ": Object not as expected" )
1910 return None
1911 except pexpect.EOF:
1912 main.log.error( self.name + ": EOF exception found" )
1913 main.log.error( self.name + ": " + self.handle.before )
1914 main.cleanup()
1915 main.exit()
1916 except Exception:
1917 main.log.exception( self.name + ": Uncaught exception!" )
1918 main.cleanup()
1919 main.exit()
1920
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001921 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001922 """
1923 Purges all WITHDRAWN Intents
1924 """
1925 try:
1926 cmdStr = "purge-intents"
1927 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001928 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001929 if re.search( "Error", handle ):
1930 main.log.error( "Error in purging intents" )
1931 return main.FALSE
1932 else:
1933 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001934 except AssertionError:
1935 main.log.exception( "" )
1936 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001937 except TypeError:
1938 main.log.exception( self.name + ": Object not as expected" )
1939 return None
1940 except pexpect.EOF:
1941 main.log.error( self.name + ": EOF exception found" )
1942 main.log.error( self.name + ": " + self.handle.before )
1943 main.cleanup()
1944 main.exit()
1945 except Exception:
1946 main.log.exception( self.name + ": Uncaught exception!" )
1947 main.cleanup()
1948 main.exit()
1949
kelvin-onlabd3b64892015-01-20 13:26:24 -08001950 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001951 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001952 NOTE: This method should be used after installing application:
1953 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001954 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001955 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001956 Description:
1957 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001958 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001960 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001961 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001962 cmdStr += " -j"
1963 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001964 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001965 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001966 except AssertionError:
1967 main.log.exception( "" )
1968 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001969 except TypeError:
1970 main.log.exception( self.name + ": Object not as expected" )
1971 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001972 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001973 main.log.error( self.name + ": EOF exception found" )
1974 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 main.cleanup()
1976 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001977 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001978 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001979 main.cleanup()
1980 main.exit()
1981
pingping-lin54b03372015-08-13 14:43:10 -07001982 def ipv4RouteNumber( self ):
1983 """
1984 NOTE: This method should be used after installing application:
1985 onos-app-sdnip
1986 Description:
1987 Obtain the total IPv4 routes number in the system
1988 """
1989 try:
1990 cmdStr = "routes -s -j"
1991 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001992 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001993 jsonResult = json.loads( handle )
1994 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001995 except AssertionError:
1996 main.log.exception( "" )
1997 return None
1998 except ( TypeError, ValueError ):
1999 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002000 return None
2001 except pexpect.EOF:
2002 main.log.error( self.name + ": EOF exception found" )
2003 main.log.error( self.name + ": " + self.handle.before )
2004 main.cleanup()
2005 main.exit()
2006 except Exception:
2007 main.log.exception( self.name + ": Uncaught exception!" )
2008 main.cleanup()
2009 main.exit()
2010
pingping-lin8244a3b2015-09-16 13:36:56 -07002011 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002012 """
andrewonlabe6745342014-10-17 14:29:13 -04002013 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002014 Obtain intents from the ONOS cli.
2015 Optional:
2016 * jsonFormat: Enable output formatting in json, default to True
2017 * summary: Whether only output the intent summary, defaults to False
2018 * type: Only output a certain type of intent. This options is valid
2019 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002020 """
andrewonlabe6745342014-10-17 14:29:13 -04002021 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002022 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002023 if summary:
2024 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002025 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002026 cmdStr += " -j"
2027 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002028 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002029 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002030 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002031 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002032 else:
Jon Hallff566d52016-01-15 14:45:36 -08002033 intentType = ""
2034 # IF we want the summary of a specific intent type
2035 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002036 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002037 if intentType in jsonResult.keys():
2038 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 else:
Jon Hallff566d52016-01-15 14:45:36 -08002040 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002041 return handle
2042 else:
2043 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002044 except AssertionError:
2045 main.log.exception( "" )
2046 return None
2047 except ( TypeError, ValueError ):
2048 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002049 return None
2050 except pexpect.EOF:
2051 main.log.error( self.name + ": EOF exception found" )
2052 main.log.error( self.name + ": " + self.handle.before )
2053 main.cleanup()
2054 main.exit()
2055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
2057 main.cleanup()
2058 main.exit()
2059
kelvin-onlab54400a92015-02-26 18:05:51 -08002060 def getIntentState(self, intentsId, intentsJson=None):
2061 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002062 Check intent state.
2063 Accepts a single intent ID (string type) or a list of intent IDs.
2064 Returns the state(string type) of the id if a single intent ID is
2065 accepted.
Jon Hallefbd9792015-03-05 16:11:36 -08002066 Returns a dictionary with intent IDs as the key and its
2067 corresponding states as the values
kelvin-onlabfb521662015-02-27 09:52:40 -08002068 Parameters:
kelvin-onlab54400a92015-02-26 18:05:51 -08002069 intentId: intent ID (string type)
2070 intentsJson: parsed json object from the onos:intents api
2071 Returns:
2072 state = An intent's state- INSTALL,WITHDRAWN etc.
2073 stateDict = Dictionary of intent's state. intent ID as the keys and
2074 state as the values.
2075 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002076 try:
2077 state = "State is Undefined"
2078 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002079 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002080 else:
Jon Hallc6793552016-01-19 14:18:37 -08002081 rawJson = intentsJson
2082 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002083 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002084 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002085 if intentsId == intent[ 'id' ]:
2086 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002087 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002088 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2089 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002090 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002091 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002092 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002093 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002094 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002095 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002096 if intentsId[ i ] == intents[ 'id' ]:
2097 stateDict[ 'state' ] = intents[ 'state' ]
2098 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002099 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002100 break
Jon Hallefbd9792015-03-05 16:11:36 -08002101 if len( intentsId ) != len( dictList ):
2102 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002103 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002104 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002105 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 return None
Jon Hallc6793552016-01-19 14:18:37 -08002107 except ( TypeError, ValueError ):
2108 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 return None
2110 except pexpect.EOF:
2111 main.log.error( self.name + ": EOF exception found" )
2112 main.log.error( self.name + ": " + self.handle.before )
2113 main.cleanup()
2114 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002115 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002116 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002117 main.cleanup()
2118 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002119
kelvin-onlabf512e942015-06-08 19:42:59 -07002120 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002121 """
2122 Description:
2123 Check intents state
2124 Required:
2125 intentsId - List of intents ID to be checked
2126 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002127 expectedState - Check the expected state(s) of each intents
2128 state in the list.
2129 *NOTE: You can pass in a list of expected state,
2130 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002132 Returns main.TRUE only if all intent are the same as expected states
2133 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002134 """
2135 try:
2136 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002137 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002138 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002139 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002140 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 "getting intents state" )
2142 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002143
2144 if isinstance( expectedState, types.StringType ):
2145 for intents in intentsDict:
2146 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002147 main.log.debug( self.name + " : Intent ID - " +
2148 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002149 " actual state = " +
2150 intents.get( 'state' )
2151 + " does not equal expected state = "
2152 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002153 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002154
2155 elif isinstance( expectedState, types.ListType ):
2156 for intents in intentsDict:
2157 if not any( state == intents.get( 'state' ) for state in
2158 expectedState ):
2159 main.log.debug( self.name + " : Intent ID - " +
2160 intents.get( 'id' ) +
2161 " actual state = " +
2162 intents.get( 'state' ) +
2163 " does not equal expected states = "
2164 + str( expectedState ) )
2165 returnValue = main.FALSE
2166
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002167 if returnValue == main.TRUE:
2168 main.log.info( self.name + ": All " +
2169 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002170 " intents are in " + str( expectedState ) +
2171 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002172 return returnValue
2173 except TypeError:
2174 main.log.exception( self.name + ": Object not as expected" )
2175 return None
2176 except pexpect.EOF:
2177 main.log.error( self.name + ": EOF exception found" )
2178 main.log.error( self.name + ": " + self.handle.before )
2179 main.cleanup()
2180 main.exit()
2181 except Exception:
2182 main.log.exception( self.name + ": Uncaught exception!" )
2183 main.cleanup()
2184 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002185
GlennRCed771242016-01-13 17:02:47 -08002186 def checkIntentSummary( self, timeout=60 ):
2187 """
2188 Description:
2189 Check the number of installed intents.
2190 Optional:
2191 timeout - the timeout for pexcept
2192 Return:
2193 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2194 , otherwise, returns main.FALSE.
2195 """
2196
2197 try:
2198 cmd = "intents -s -j"
2199
2200 # Check response if something wrong
2201 response = self.sendline( cmd, timeout=timeout )
2202 if response == None:
2203 return main.False
2204 response = json.loads( response )
2205
2206 # get total and installed number, see if they are match
2207 allState = response.get( 'all' )
2208 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002209 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002210 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002211 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002212 return main.FALSE
2213
Jon Hallc6793552016-01-19 14:18:37 -08002214 except ( TypeError, ValueError ):
2215 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002216 return None
2217 except pexpect.EOF:
2218 main.log.error( self.name + ": EOF exception found" )
2219 main.log.error( self.name + ": " + self.handle.before )
2220 main.cleanup()
2221 main.exit()
2222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
2224 main.cleanup()
2225 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002226 except pexpect.TIMEOUT:
2227 main.log.error( self.name + ": ONOS timeout" )
2228 return None
GlennRCed771242016-01-13 17:02:47 -08002229
YPZhangebf9eb52016-05-12 15:20:24 -07002230 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002231 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002232 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002233 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002234 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002235 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002236 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002237 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002238 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002239 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002240 cmdStr += " -j "
2241 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002242 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002243 assert "Command not found:" not in handle, handle
2244 if re.search( "Error:", handle ):
2245 main.log.error( self.name + ": flows() response: " +
2246 str( handle ) )
2247 return handle
2248 except AssertionError:
2249 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002250 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002251 except TypeError:
2252 main.log.exception( self.name + ": Object not as expected" )
2253 return None
Jon Hallc6793552016-01-19 14:18:37 -08002254 except pexpect.TIMEOUT:
2255 main.log.error( self.name + ": ONOS timeout" )
2256 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002260 main.cleanup()
2261 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002262 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002263 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002264 main.cleanup()
2265 main.exit()
2266
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002267 def checkFlowCount(self, min=0, timeout=60 ):
2268 count = int(self.getTotalFlowsNum( timeout=timeout ))
2269 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002270
YPZhangebf9eb52016-05-12 15:20:24 -07002271 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002272 """
2273 Description:
GlennRCed771242016-01-13 17:02:47 -08002274 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002275 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2276 if the count of those states is 0, which means all current flows
2277 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002278 Optional:
GlennRCed771242016-01-13 17:02:47 -08002279 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002280 Return:
2281 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002282 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002283 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002284 """
2285 try:
GlennRCed771242016-01-13 17:02:47 -08002286 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2287 checkedStates = []
2288 statesCount = [0, 0, 0, 0]
2289 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002290 rawFlows = self.flows( state=s, timeout = timeout )
2291 checkedStates.append( json.loads( rawFlows ) )
2292 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002293 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002294 try:
2295 statesCount[i] += int( c.get( "flowCount" ) )
2296 except TypeError:
2297 main.log.exception( "Json object not as expected" )
2298 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002299
GlennRCed771242016-01-13 17:02:47 -08002300 # We want to count PENDING_ADD if isPENDING is true
2301 if isPENDING:
2302 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2303 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002304 else:
GlennRCed771242016-01-13 17:02:47 -08002305 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2306 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002307 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002308 except ( TypeError, ValueError ):
2309 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002310 return None
2311 except pexpect.EOF:
2312 main.log.error( self.name + ": EOF exception found" )
2313 main.log.error( self.name + ": " + self.handle.before )
2314 main.cleanup()
2315 main.exit()
2316 except Exception:
2317 main.log.exception( self.name + ": Uncaught exception!" )
2318 main.cleanup()
2319 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002320 except pexpect.TIMEOUT:
2321 main.log.error( self.name + ": ONOS timeout" )
2322 return None
2323
kelvin-onlab4df89f22015-04-13 18:10:23 -07002324
GlennRCed771242016-01-13 17:02:47 -08002325 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangebf9eb52016-05-12 15:20:24 -07002326 options="", timeout=10, background = False, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002327 """
andrewonlab87852b02014-11-19 18:44:19 -05002328 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002329 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002330 a specific point-to-point intent definition
2331 Required:
GlennRCed771242016-01-13 17:02:47 -08002332 * ingress: specify source dpid
2333 * egress: specify destination dpid
2334 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002335 Optional:
GlennRCed771242016-01-13 17:02:47 -08002336 * offset: the keyOffset is where the next batch of intents
2337 will be installed
2338 Returns: If failed to push test intents, it will returen None,
2339 if successful, return true.
2340 Timeout expection will return None,
2341 TypeError will return false
2342 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002343 """
andrewonlab87852b02014-11-19 18:44:19 -05002344 try:
GlennRCed771242016-01-13 17:02:47 -08002345 if background:
2346 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002347 else:
GlennRCed771242016-01-13 17:02:47 -08002348 back = ""
2349 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002350 ingress,
2351 egress,
2352 batchSize,
2353 offset,
2354 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002355 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002356 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002357 main.log.info( response )
2358 if response == None:
2359 return None
2360
2361 # TODO: We should handle if there is failure in installation
2362 return main.TRUE
2363
Jon Hallc6793552016-01-19 14:18:37 -08002364 except AssertionError:
2365 main.log.exception( "" )
2366 return None
GlennRCed771242016-01-13 17:02:47 -08002367 except pexpect.TIMEOUT:
2368 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002369 return None
andrewonlab87852b02014-11-19 18:44:19 -05002370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002371 main.log.error( self.name + ": EOF exception found" )
2372 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002373 main.cleanup()
2374 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002375 except TypeError:
2376 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002377 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002378 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002379 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002380 main.cleanup()
2381 main.exit()
2382
YPZhangebf9eb52016-05-12 15:20:24 -07002383 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002384 """
2385 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002386 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002387 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002388 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002389 """
YPZhange3109a72016-02-02 11:25:37 -08002390
YPZhangb5d3f832016-01-23 22:54:26 -08002391 try:
YPZhange3109a72016-02-02 11:25:37 -08002392 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002393 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002394 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002395
2396 if totalFlows == None:
2397 # if timeout, we will get total number of all flows, and subtract other states
2398 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2399 checkedStates = []
2400 totalFlows = 0
2401 statesCount = [0, 0, 0, 0]
2402
2403 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002404 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002405 totalFlows = int( response.get("flows") )
2406
2407 for s in states:
2408 rawFlows = self.flows( state=s, timeout = timeout )
2409 if rawFlows == None:
2410 # if timeout, return the total flows number from summary command
2411 return totalFlows
2412 checkedStates.append( json.loads( rawFlows ) )
2413
2414 # Calculate ADDED flows number, equal total subtracts others
2415 for i in range( len( states ) ):
2416 for c in checkedStates[i]:
2417 try:
2418 statesCount[i] += int( c.get( "flowCount" ) )
2419 except TypeError:
2420 main.log.exception( "Json object not as expected" )
2421 totalFlows = totalFlows - int( statesCount[i] )
2422 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2423
2424 return totalFlows
2425
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002426 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002427
YPZhangb5d3f832016-01-23 22:54:26 -08002428 except TypeError:
2429 main.log.exception( self.name + ": Object not as expected" )
2430 return None
2431 except pexpect.EOF:
2432 main.log.error( self.name + ": EOF exception found" )
2433 main.log.error( self.name + ": " + self.handle.before )
2434 main.cleanup()
2435 main.exit()
2436 except Exception:
2437 main.log.exception( self.name + ": Uncaught exception!" )
2438 main.cleanup()
2439 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002440 except pexpect.TIMEOUT:
2441 main.log.error( self.name + ": ONOS timeout" )
2442 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002443
YPZhangebf9eb52016-05-12 15:20:24 -07002444 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002445 """
2446 Description:
2447 Get the total number of intents, include every states.
2448 Return:
2449 The number of intents
2450 """
2451 try:
2452 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002453 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002454 if response == None:
2455 return -1
2456 response = json.loads( response )
2457 return int( response.get("intents") )
2458 except TypeError:
2459 main.log.exception( self.name + ": Object not as expected" )
2460 return None
2461 except pexpect.EOF:
2462 main.log.error( self.name + ": EOF exception found" )
2463 main.log.error( self.name + ": " + self.handle.before )
2464 main.cleanup()
2465 main.exit()
2466 except Exception:
2467 main.log.exception( self.name + ": Uncaught exception!" )
2468 main.cleanup()
2469 main.exit()
2470
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002472 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002473 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002474 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002475 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002476 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002477 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002478 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002479 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002480 cmdStr += " -j"
2481 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002482 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002483 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002484 except AssertionError:
2485 main.log.exception( "" )
2486 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002487 except TypeError:
2488 main.log.exception( self.name + ": Object not as expected" )
2489 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002490 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002493 main.cleanup()
2494 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002495 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002496 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002497 main.cleanup()
2498 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002499
kelvin-onlabd3b64892015-01-20 13:26:24 -08002500 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002501 """
2502 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002503 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002504 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002505 """
andrewonlab867212a2014-10-22 20:13:38 -04002506 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002507 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002508 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002509 cmdStr += " -j"
2510 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002511 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002512 if handle:
2513 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002514 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002515 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002516 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002517 else:
2518 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002519 except AssertionError:
2520 main.log.exception( "" )
2521 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002522 except TypeError:
2523 main.log.exception( self.name + ": Object not as expected" )
2524 return None
andrewonlab867212a2014-10-22 20:13:38 -04002525 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002526 main.log.error( self.name + ": EOF exception found" )
2527 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002528 main.cleanup()
2529 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002530 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002531 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002532 main.cleanup()
2533 main.exit()
2534
kelvin8ec71442015-01-15 16:57:00 -08002535 # Wrapper functions ****************
2536 # Wrapper functions use existing driver
2537 # functions and extends their use case.
2538 # For example, we may use the output of
2539 # a normal driver function, and parse it
2540 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002541
kelvin-onlabd3b64892015-01-20 13:26:24 -08002542 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002543 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002544 Description:
2545 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002546 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002547 try:
kelvin8ec71442015-01-15 16:57:00 -08002548 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002549 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002550 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002551
kelvin8ec71442015-01-15 16:57:00 -08002552 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002553 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2554 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002555 match = re.search('id=0x([\da-f]+),', intents)
2556 if match:
2557 tmpId = match.group()[3:-1]
2558 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002559 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002560
Jon Halld4d4b372015-01-28 16:02:41 -08002561 except TypeError:
2562 main.log.exception( self.name + ": Object not as expected" )
2563 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002564 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002565 main.log.error( self.name + ": EOF exception found" )
2566 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002567 main.cleanup()
2568 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002569 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002570 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002571 main.cleanup()
2572 main.exit()
2573
Jon Hall30b82fa2015-03-04 17:15:43 -08002574 def FlowAddedCount( self, deviceId ):
2575 """
2576 Determine the number of flow rules for the given device id that are
2577 in the added state
2578 """
2579 try:
2580 cmdStr = "flows any " + str( deviceId ) + " | " +\
2581 "grep 'state=ADDED' | wc -l"
2582 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002583 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002584 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002585 except AssertionError:
2586 main.log.exception( "" )
2587 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002588 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08002593 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002594 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002595 main.cleanup()
2596 main.exit()
2597
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002599 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002600 Use 'devices' function to obtain list of all devices
2601 and parse the result to obtain a list of all device
2602 id's. Returns this list. Returns empty list if no
2603 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002604 List is ordered sequentially
2605
andrewonlab3e15ead2014-10-15 14:21:34 -04002606 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002607 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002608 the ids. By obtaining the list of device ids on the fly,
2609 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002610 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002611 try:
kelvin8ec71442015-01-15 16:57:00 -08002612 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002613 devicesStr = self.devices( jsonFormat=False )
2614 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002615
kelvin-onlabd3b64892015-01-20 13:26:24 -08002616 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002617 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 return idList
kelvin8ec71442015-01-15 16:57:00 -08002619
2620 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002621 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002622 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002623 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002624 # Split list further into arguments before and after string
2625 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002626 # append to idList
2627 for arg in tempList:
2628 idList.append( arg.split( "id=" )[ 1 ] )
2629 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002630
Jon Halld4d4b372015-01-28 16:02:41 -08002631 except TypeError:
2632 main.log.exception( self.name + ": Object not as expected" )
2633 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002634 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002635 main.log.error( self.name + ": EOF exception found" )
2636 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002637 main.cleanup()
2638 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002639 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002640 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002641 main.cleanup()
2642 main.exit()
2643
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002645 """
andrewonlab7c211572014-10-15 16:45:20 -04002646 Uses 'nodes' function to obtain list of all nodes
2647 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002648 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002649 Returns:
2650 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002651 """
andrewonlab7c211572014-10-15 16:45:20 -04002652 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002653 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002654 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002655 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002656 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002657 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002658 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002659 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002660 nodesJson = json.loads( nodesStr )
2661 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002663 except ( TypeError, ValueError ):
2664 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002665 return None
andrewonlab7c211572014-10-15 16:45:20 -04002666 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002667 main.log.error( self.name + ": EOF exception found" )
2668 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002669 main.cleanup()
2670 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002671 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002672 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002673 main.cleanup()
2674 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002675
kelvin-onlabd3b64892015-01-20 13:26:24 -08002676 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002677 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002678 Return the first device from the devices api whose 'id' contains 'dpid'
2679 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002680 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002681 try:
kelvin8ec71442015-01-15 16:57:00 -08002682 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002683 return None
2684 else:
kelvin8ec71442015-01-15 16:57:00 -08002685 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 rawDevices = self.devices()
2687 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002688 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002689 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002690 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2691 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002692 return device
2693 return None
Jon Hallc6793552016-01-19 14:18:37 -08002694 except ( TypeError, ValueError ):
2695 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002696 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002698 main.log.error( self.name + ": EOF exception found" )
2699 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002700 main.cleanup()
2701 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002703 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002704 main.cleanup()
2705 main.exit()
2706
You Wang24139872016-05-03 11:48:47 -07002707 def getTopology( self, topologyOutput ):
2708 """
2709 Definition:
2710 Loads a json topology output
2711 Return:
2712 topology = current ONOS topology
2713 """
2714 import json
2715 try:
2716 # either onos:topology or 'topology' will work in CLI
2717 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002718 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002719 return topology
2720 except pexpect.EOF:
2721 main.log.error( self.name + ": EOF exception found" )
2722 main.log.error( self.name + ": " + self.handle.before )
2723 main.cleanup()
2724 main.exit()
2725 except Exception:
2726 main.log.exception( self.name + ": Uncaught exception!" )
2727 main.cleanup()
2728 main.exit()
2729
2730 def checkStatus(
2731 self,
2732 topologyResult,
2733 numoswitch,
2734 numolink,
2735 logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002736 """
Jon Hallefbd9792015-03-05 16:11:36 -08002737 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002738 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002739 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002740
You Wang24139872016-05-03 11:48:47 -07002741 Params: topologyResult = the output of topology command
Jon Hall42db6dc2014-10-24 19:03:48 -04002742 numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002743 numolink = expected number of links
You Wang24139872016-05-03 11:48:47 -07002744 logLevel = level to log to.
2745 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002746
Jon Hallefbd9792015-03-05 16:11:36 -08002747 Returns: main.TRUE if the number of switches and links are correct,
2748 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002749 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002750 """
Jon Hall42db6dc2014-10-24 19:03:48 -04002751 try:
You Wang24139872016-05-03 11:48:47 -07002752 topology = self.getTopology( topologyResult )
Jon Hall42db6dc2014-10-24 19:03:48 -04002753 if topology == {}:
2754 return main.ERROR
2755 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002756 # Is the number of switches is what we expected
2757 devices = topology.get( 'devices', False )
2758 links = topology.get( 'links', False )
kelvin-onlabfb521662015-02-27 09:52:40 -08002759 if devices is False or links is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002760 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002761 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002762 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002763 linkCheck = ( int( links ) == int( numolink ) )
You Wang24139872016-05-03 11:48:47 -07002764 if switchCheck and linkCheck:
kelvin8ec71442015-01-15 16:57:00 -08002765 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002766 output = output + "The number of links and switches match "\
2767 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002768 result = main.TRUE
2769 else:
You Wang24139872016-05-03 11:48:47 -07002770 output = output + \
2771 "The number of links and switches does not match " + \
2772 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002773 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002774 output = output + "\n ONOS sees %i devices" % int( devices )
2775 output = output + " (%i expected) " % int( numoswitch )
2776 output = output + "and %i links " % int( links )
2777 output = output + "(%i expected)" % int( numolink )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002779 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002780 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002781 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002782 else:
You Wang24139872016-05-03 11:48:47 -07002783 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002784 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002785 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 Hall42db6dc2014-10-24 19:03:48 -04002788 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 Hall42db6dc2014-10-24 19:03:48 -04002792 main.cleanup()
2793 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002794
kelvin-onlabd3b64892015-01-20 13:26:24 -08002795 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002796 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002797 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002798 deviceId must be the id of a device as seen in the onos devices command
2799 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002800 role must be either master, standby, or none
2801
Jon Halle3f39ff2015-01-13 11:50:53 -08002802 Returns:
2803 main.TRUE or main.FALSE based on argument verification and
2804 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002805 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002806 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002807 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002808 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002809 cmdStr = "device-role " +\
2810 str( deviceId ) + " " +\
2811 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002812 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002814 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002815 if re.search( "Error", handle ):
2816 # end color output to escape any colours
2817 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002818 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002819 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002820 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002821 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002822 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002823 main.log.error( "Invalid 'role' given to device_role(). " +
2824 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002825 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002826 except AssertionError:
2827 main.log.exception( "" )
2828 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002829 except TypeError:
2830 main.log.exception( self.name + ": Object not as expected" )
2831 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002832 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002833 main.log.error( self.name + ": EOF exception found" )
2834 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002835 main.cleanup()
2836 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002838 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002839 main.cleanup()
2840 main.exit()
2841
kelvin-onlabd3b64892015-01-20 13:26:24 -08002842 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002843 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002844 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002845 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002846 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002847 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002848 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002849 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002850 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002851 cmdStr += " -j"
2852 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002853 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002854 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002855 except AssertionError:
2856 main.log.exception( "" )
2857 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002858 except TypeError:
2859 main.log.exception( self.name + ": Object not as expected" )
2860 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002864 main.cleanup()
2865 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002867 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002868 main.cleanup()
2869 main.exit()
2870
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002872 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002873 CLI command to get the current leader for the Election test application
2874 NOTE: Requires installation of the onos-app-election feature
2875 Returns: Node IP of the leader if one exists
2876 None if none exists
2877 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002878 """
Jon Hall94fd0472014-12-08 11:52:42 -08002879 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002880 cmdStr = "election-test-leader"
2881 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002882 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002883 # Leader
2884 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002885 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002886 nodeSearch = re.search( leaderPattern, response )
2887 if nodeSearch:
2888 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002889 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002890 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002891 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002892 # no leader
2893 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002894 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002895 nullSearch = re.search( nullPattern, response )
2896 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002897 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002898 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002899 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002900 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002901 errorPattern = "Command\snot\sfound"
kelvin-onlab898a6c62015-01-16 14:13:53 -08002902 if re.search( errorPattern, response ):
2903 main.log.error( "Election app is not loaded on " + self.name )
Jon Halle3f39ff2015-01-13 11:50:53 -08002904 # TODO: Should this be main.ERROR?
Jon Hall669173b2014-12-17 11:36:30 -08002905 return main.FALSE
2906 else:
Jon Hall390696c2015-05-05 17:13:41 -07002907 main.log.error( "Error in electionTestLeader on " + self.name +
2908 ": " + "unexpected response" )
kelvin8ec71442015-01-15 16:57:00 -08002909 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002910 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002911 except AssertionError:
2912 main.log.exception( "" )
2913 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002914 except TypeError:
2915 main.log.exception( self.name + ": Object not as expected" )
2916 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002918 main.log.error( self.name + ": EOF exception found" )
2919 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002920 main.cleanup()
2921 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002922 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002923 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002924 main.cleanup()
2925 main.exit()
2926
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002928 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002929 CLI command to run for leadership of the Election test application.
2930 NOTE: Requires installation of the onos-app-election feature
2931 Returns: Main.TRUE on success
2932 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002933 """
Jon Hall94fd0472014-12-08 11:52:42 -08002934 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002935 cmdStr = "election-test-run"
2936 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002937 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002938 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002939 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002940 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002941 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08002942 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08002943 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002944 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002945 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002946 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002947 errorPattern = "Command\snot\sfound"
2948 if re.search( errorPattern, response ):
2949 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002950 return main.FALSE
2951 else:
Jon Hall390696c2015-05-05 17:13:41 -07002952 main.log.error( "Error in electionTestRun on " + self.name +
2953 ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002954 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08002955 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002956 except AssertionError:
2957 main.log.exception( "" )
2958 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002959 except TypeError:
2960 main.log.exception( self.name + ": Object not as expected" )
2961 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002962 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002963 main.log.error( self.name + ": EOF exception found" )
2964 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002965 main.cleanup()
2966 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002967 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002968 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002969 main.cleanup()
2970 main.exit()
2971
kelvin-onlabd3b64892015-01-20 13:26:24 -08002972 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08002973 """
Jon Hall94fd0472014-12-08 11:52:42 -08002974 * CLI command to withdraw the local node from leadership election for
2975 * the Election test application.
2976 #NOTE: Requires installation of the onos-app-election feature
2977 Returns: Main.TRUE on success
2978 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08002979 """
Jon Hall94fd0472014-12-08 11:52:42 -08002980 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 cmdStr = "election-test-withdraw"
2982 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002983 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08002984 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08002985 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002986 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08002987 if re.search( successPattern, response ):
2988 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002989 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08002990 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08002991 # error
Jon Halle3f39ff2015-01-13 11:50:53 -08002992 errorPattern = "Command\snot\sfound"
2993 if re.search( errorPattern, response ):
2994 main.log.error( "Election app is not loaded on " + self.name )
Jon Hall669173b2014-12-17 11:36:30 -08002995 return main.FALSE
2996 else:
Jon Hall390696c2015-05-05 17:13:41 -07002997 main.log.error( "Error in electionTestWithdraw on " +
2998 self.name + ": " + "unexpected response" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002999 main.log.error( repr( response ) )
Jon Hall669173b2014-12-17 11:36:30 -08003000 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003001 except AssertionError:
3002 main.log.exception( "" )
3003 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003004 except TypeError:
3005 main.log.exception( self.name + ": Object not as expected" )
3006 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003008 main.log.error( self.name + ": EOF exception found" )
3009 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003010 main.cleanup()
3011 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003012 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003013 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003014 main.cleanup()
3015 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003016
kelvin8ec71442015-01-15 16:57:00 -08003017 def getDevicePortsEnabledCount( self, dpid ):
3018 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003019 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003020 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003021 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003022 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003023 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3024 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003025 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003026 if re.search( "No such device", output ):
3027 main.log.error( "Error in getting ports" )
3028 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003029 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003030 return output
Jon Hallc6793552016-01-19 14:18:37 -08003031 except AssertionError:
3032 main.log.exception( "" )
3033 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003034 except TypeError:
3035 main.log.exception( self.name + ": Object not as expected" )
3036 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003038 main.log.error( self.name + ": EOF exception found" )
3039 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003040 main.cleanup()
3041 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003042 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003043 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003044 main.cleanup()
3045 main.exit()
3046
kelvin8ec71442015-01-15 16:57:00 -08003047 def getDeviceLinksActiveCount( self, dpid ):
3048 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003049 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003050 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003051 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003052 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003053 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3054 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003055 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003056 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003057 main.log.error( "Error in getting ports " )
3058 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003059 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003060 return output
Jon Hallc6793552016-01-19 14:18:37 -08003061 except AssertionError:
3062 main.log.exception( "" )
3063 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003064 except TypeError:
3065 main.log.exception( self.name + ": Object not as expected" )
3066 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003068 main.log.error( self.name + ": EOF exception found" )
3069 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003070 main.cleanup()
3071 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003072 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003073 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003074 main.cleanup()
3075 main.exit()
3076
kelvin8ec71442015-01-15 16:57:00 -08003077 def getAllIntentIds( self ):
3078 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003079 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003080 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003081 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003082 cmdStr = "onos:intents | grep id="
3083 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003084 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003085 if re.search( "Error", output ):
3086 main.log.error( "Error in getting ports" )
3087 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003088 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08003089 return output
Jon Hallc6793552016-01-19 14:18:37 -08003090 except AssertionError:
3091 main.log.exception( "" )
3092 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003093 except TypeError:
3094 main.log.exception( self.name + ": Object not as expected" )
3095 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003096 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003097 main.log.error( self.name + ": EOF exception found" )
3098 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003099 main.cleanup()
3100 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003101 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003102 main.log.exception( self.name + ": Uncaught exception!" )
3103 main.cleanup()
3104 main.exit()
3105
Jon Hall73509952015-02-24 16:42:56 -08003106 def intentSummary( self ):
3107 """
Jon Hallefbd9792015-03-05 16:11:36 -08003108 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003109 """
3110 try:
3111 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003112 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003113 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003114 states.append( intent.get( 'state', None ) )
3115 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003116 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003117 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003118 except ( TypeError, ValueError ):
3119 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003120 return None
3121 except pexpect.EOF:
3122 main.log.error( self.name + ": EOF exception found" )
3123 main.log.error( self.name + ": " + self.handle.before )
3124 main.cleanup()
3125 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003126 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003127 main.log.exception( self.name + ": Uncaught exception!" )
3128 main.cleanup()
3129 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003130
Jon Hall61282e32015-03-19 11:34:11 -07003131 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003132 """
3133 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003134 Optional argument:
3135 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003136 """
Jon Hall63604932015-02-26 17:09:50 -08003137 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003138 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003139 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003140 cmdStr += " -j"
3141 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003142 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003143 return output
Jon Hallc6793552016-01-19 14:18:37 -08003144 except AssertionError:
3145 main.log.exception( "" )
3146 return None
Jon Hall63604932015-02-26 17:09:50 -08003147 except TypeError:
3148 main.log.exception( self.name + ": Object not as expected" )
3149 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003150 except pexpect.EOF:
3151 main.log.error( self.name + ": EOF exception found" )
3152 main.log.error( self.name + ": " + self.handle.before )
3153 main.cleanup()
3154 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003155 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003156 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003157 main.cleanup()
3158 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003159
acsmarsa4a4d1e2015-07-10 16:01:24 -07003160 def leaderCandidates( self, jsonFormat=True ):
3161 """
3162 Returns the output of the leaders -c command.
3163 Optional argument:
3164 * jsonFormat - boolean indicating if you want output in json
3165 """
3166 try:
3167 cmdStr = "onos:leaders -c"
3168 if jsonFormat:
3169 cmdStr += " -j"
3170 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003171 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003172 return output
Jon Hallc6793552016-01-19 14:18:37 -08003173 except AssertionError:
3174 main.log.exception( "" )
3175 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003176 except TypeError:
3177 main.log.exception( self.name + ": Object not as expected" )
3178 return None
3179 except pexpect.EOF:
3180 main.log.error( self.name + ": EOF exception found" )
3181 main.log.error( self.name + ": " + self.handle.before )
3182 main.cleanup()
3183 main.exit()
3184 except Exception:
3185 main.log.exception( self.name + ": Uncaught exception!" )
3186 main.cleanup()
3187 main.exit()
3188
Jon Hallc6793552016-01-19 14:18:37 -08003189 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003190 """
3191 Returns a list in format [leader,candidate1,candidate2,...] for a given
3192 topic parameter and an empty list if the topic doesn't exist
3193 If no leader is elected leader in the returned list will be "none"
3194 Returns None if there is a type error processing the json object
3195 """
3196 try:
Jon Hall6e709752016-02-01 13:38:46 -08003197 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003198 rawOutput = self.sendline( cmdStr )
3199 assert "Command not found:" not in rawOutput, rawOutput
3200 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003201 results = []
3202 for dict in output:
3203 if dict["topic"] == topic:
3204 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003205 candidates = re.split( ", ", dict["candidates"][1:-1] )
3206 results.append( leader )
3207 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003208 return results
Jon Hallc6793552016-01-19 14:18:37 -08003209 except AssertionError:
3210 main.log.exception( "" )
3211 return None
3212 except ( TypeError, ValueError ):
3213 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003214 return None
3215 except pexpect.EOF:
3216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
3218 main.cleanup()
3219 main.exit()
3220 except Exception:
3221 main.log.exception( self.name + ": Uncaught exception!" )
3222 main.cleanup()
3223 main.exit()
3224
Jon Hall61282e32015-03-19 11:34:11 -07003225 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003226 """
3227 Returns the output of the intent Pending map.
3228 """
Jon Hall63604932015-02-26 17:09:50 -08003229 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003230 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003231 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003232 cmdStr += " -j"
3233 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003234 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003235 return output
Jon Hallc6793552016-01-19 14:18:37 -08003236 except AssertionError:
3237 main.log.exception( "" )
3238 return None
Jon Hall63604932015-02-26 17:09:50 -08003239 except TypeError:
3240 main.log.exception( self.name + ": Object not as expected" )
3241 return None
3242 except pexpect.EOF:
3243 main.log.error( self.name + ": EOF exception found" )
3244 main.log.error( self.name + ": " + self.handle.before )
3245 main.cleanup()
3246 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003247 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003248 main.log.exception( self.name + ": Uncaught exception!" )
3249 main.cleanup()
3250 main.exit()
3251
Jon Hall61282e32015-03-19 11:34:11 -07003252 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003253 """
3254 Returns the output of the raft partitions command for ONOS.
3255 """
Jon Hall61282e32015-03-19 11:34:11 -07003256 # Sample JSON
3257 # {
3258 # "leader": "tcp://10.128.30.11:7238",
3259 # "members": [
3260 # "tcp://10.128.30.11:7238",
3261 # "tcp://10.128.30.17:7238",
3262 # "tcp://10.128.30.13:7238",
3263 # ],
3264 # "name": "p1",
3265 # "term": 3
3266 # },
Jon Hall63604932015-02-26 17:09:50 -08003267 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003268 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003269 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003270 cmdStr += " -j"
3271 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003272 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003273 return output
Jon Hallc6793552016-01-19 14:18:37 -08003274 except AssertionError:
3275 main.log.exception( "" )
3276 return None
Jon Hall63604932015-02-26 17:09:50 -08003277 except TypeError:
3278 main.log.exception( self.name + ": Object not as expected" )
3279 return None
3280 except pexpect.EOF:
3281 main.log.error( self.name + ": EOF exception found" )
3282 main.log.error( self.name + ": " + self.handle.before )
3283 main.cleanup()
3284 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003285 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003286 main.log.exception( self.name + ": Uncaught exception!" )
3287 main.cleanup()
3288 main.exit()
3289
Jon Hallbe379602015-03-24 13:39:32 -07003290 def apps( self, jsonFormat=True ):
3291 """
3292 Returns the output of the apps command for ONOS. This command lists
3293 information about installed ONOS applications
3294 """
3295 # Sample JSON object
3296 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3297 # "description":"ONOS OpenFlow protocol southbound providers",
3298 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3299 # "features":"[onos-openflow]","state":"ACTIVE"}]
3300 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003301 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003302 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003303 cmdStr += " -j"
3304 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003305 assert "Command not found:" not in output, output
3306 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003307 return output
Jon Hallbe379602015-03-24 13:39:32 -07003308 # FIXME: look at specific exceptions/Errors
3309 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003310 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003311 return None
3312 except TypeError:
3313 main.log.exception( self.name + ": Object not as expected" )
3314 return None
3315 except pexpect.EOF:
3316 main.log.error( self.name + ": EOF exception found" )
3317 main.log.error( self.name + ": " + self.handle.before )
3318 main.cleanup()
3319 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003320 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003321 main.log.exception( self.name + ": Uncaught exception!" )
3322 main.cleanup()
3323 main.exit()
3324
Jon Hall146f1522015-03-24 15:33:24 -07003325 def appStatus( self, appName ):
3326 """
3327 Uses the onos:apps cli command to return the status of an application.
3328 Returns:
3329 "ACTIVE" - If app is installed and activated
3330 "INSTALLED" - If app is installed and deactivated
3331 "UNINSTALLED" - If app is not installed
3332 None - on error
3333 """
Jon Hall146f1522015-03-24 15:33:24 -07003334 try:
3335 if not isinstance( appName, types.StringType ):
3336 main.log.error( self.name + ".appStatus(): appName must be" +
3337 " a string" )
3338 return None
3339 output = self.apps( jsonFormat=True )
3340 appsJson = json.loads( output )
3341 state = None
3342 for app in appsJson:
3343 if appName == app.get('name'):
3344 state = app.get('state')
3345 break
3346 if state == "ACTIVE" or state == "INSTALLED":
3347 return state
3348 elif state is None:
3349 return "UNINSTALLED"
3350 elif state:
3351 main.log.error( "Unexpected state from 'onos:apps': " +
3352 str( state ) )
3353 return state
Jon Hallc6793552016-01-19 14:18:37 -08003354 except ( TypeError, ValueError ):
3355 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003356 return None
3357 except pexpect.EOF:
3358 main.log.error( self.name + ": EOF exception found" )
3359 main.log.error( self.name + ": " + self.handle.before )
3360 main.cleanup()
3361 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003362 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003363 main.log.exception( self.name + ": Uncaught exception!" )
3364 main.cleanup()
3365 main.exit()
3366
Jon Hallbe379602015-03-24 13:39:32 -07003367 def app( self, appName, option ):
3368 """
3369 Interacts with the app command for ONOS. This command manages
3370 application inventory.
3371 """
Jon Hallbe379602015-03-24 13:39:32 -07003372 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003373 # Validate argument types
3374 valid = True
3375 if not isinstance( appName, types.StringType ):
3376 main.log.error( self.name + ".app(): appName must be a " +
3377 "string" )
3378 valid = False
3379 if not isinstance( option, types.StringType ):
3380 main.log.error( self.name + ".app(): option must be a string" )
3381 valid = False
3382 if not valid:
3383 return main.FALSE
3384 # Validate Option
3385 option = option.lower()
3386 # NOTE: Install may become a valid option
3387 if option == "activate":
3388 pass
3389 elif option == "deactivate":
3390 pass
3391 elif option == "uninstall":
3392 pass
3393 else:
3394 # Invalid option
3395 main.log.error( "The ONOS app command argument only takes " +
3396 "the values: (activate|deactivate|uninstall)" +
3397 "; was given '" + option + "'")
3398 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003399 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003400 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003401 if "Error executing command" in output:
3402 main.log.error( "Error in processing onos:app command: " +
3403 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003404 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003405 elif "No such application" in output:
3406 main.log.error( "The application '" + appName +
3407 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003408 return main.FALSE
3409 elif "Command not found:" in output:
3410 main.log.error( "Error in processing onos:app command: " +
3411 str( output ) )
3412 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003413 elif "Unsupported command:" in output:
3414 main.log.error( "Incorrect command given to 'app': " +
3415 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003416 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003417 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003418 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003419 return main.TRUE
3420 except TypeError:
3421 main.log.exception( self.name + ": Object not as expected" )
3422 return main.ERROR
3423 except pexpect.EOF:
3424 main.log.error( self.name + ": EOF exception found" )
3425 main.log.error( self.name + ": " + self.handle.before )
3426 main.cleanup()
3427 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003428 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003429 main.log.exception( self.name + ": Uncaught exception!" )
3430 main.cleanup()
3431 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003432
Jon Hallbd16b922015-03-26 17:53:15 -07003433 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003434 """
3435 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003436 appName is the hierarchical app name, not the feature name
3437 If check is True, method will check the status of the app after the
3438 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003439 Returns main.TRUE if the command was successfully sent
3440 main.FALSE if the cli responded with an error or given
3441 incorrect input
3442 """
3443 try:
3444 if not isinstance( appName, types.StringType ):
3445 main.log.error( self.name + ".activateApp(): appName must be" +
3446 " a string" )
3447 return main.FALSE
3448 status = self.appStatus( appName )
3449 if status == "INSTALLED":
3450 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003451 if check and response == main.TRUE:
3452 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003453 status = self.appStatus( appName )
3454 if status == "ACTIVE":
3455 return main.TRUE
3456 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003457 main.log.debug( "The state of application " +
3458 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003459 time.sleep( 1 )
3460 return main.FALSE
3461 else: # not 'check' or command didn't succeed
3462 return response
Jon Hall146f1522015-03-24 15:33:24 -07003463 elif status == "ACTIVE":
3464 return main.TRUE
3465 elif status == "UNINSTALLED":
3466 main.log.error( self.name + ": Tried to activate the " +
3467 "application '" + appName + "' which is not " +
3468 "installed." )
3469 else:
3470 main.log.error( "Unexpected return value from appStatus: " +
3471 str( status ) )
3472 return main.ERROR
3473 except TypeError:
3474 main.log.exception( self.name + ": Object not as expected" )
3475 return main.ERROR
3476 except pexpect.EOF:
3477 main.log.error( self.name + ": EOF exception found" )
3478 main.log.error( self.name + ": " + self.handle.before )
3479 main.cleanup()
3480 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003481 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003482 main.log.exception( self.name + ": Uncaught exception!" )
3483 main.cleanup()
3484 main.exit()
3485
Jon Hallbd16b922015-03-26 17:53:15 -07003486 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003487 """
3488 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003489 appName is the hierarchical app name, not the feature name
3490 If check is True, method will check the status of the app after the
3491 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003492 Returns main.TRUE if the command was successfully sent
3493 main.FALSE if the cli responded with an error or given
3494 incorrect input
3495 """
3496 try:
3497 if not isinstance( appName, types.StringType ):
3498 main.log.error( self.name + ".deactivateApp(): appName must " +
3499 "be a string" )
3500 return main.FALSE
3501 status = self.appStatus( appName )
3502 if status == "INSTALLED":
3503 return main.TRUE
3504 elif status == "ACTIVE":
3505 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003506 if check and response == main.TRUE:
3507 for i in range(10): # try 10 times then give up
3508 status = self.appStatus( appName )
3509 if status == "INSTALLED":
3510 return main.TRUE
3511 else:
3512 time.sleep( 1 )
3513 return main.FALSE
3514 else: # not check or command didn't succeed
3515 return response
Jon Hall146f1522015-03-24 15:33:24 -07003516 elif status == "UNINSTALLED":
3517 main.log.warn( self.name + ": Tried to deactivate the " +
3518 "application '" + appName + "' which is not " +
3519 "installed." )
3520 return main.TRUE
3521 else:
3522 main.log.error( "Unexpected return value from appStatus: " +
3523 str( status ) )
3524 return main.ERROR
3525 except TypeError:
3526 main.log.exception( self.name + ": Object not as expected" )
3527 return main.ERROR
3528 except pexpect.EOF:
3529 main.log.error( self.name + ": EOF exception found" )
3530 main.log.error( self.name + ": " + self.handle.before )
3531 main.cleanup()
3532 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003533 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003534 main.log.exception( self.name + ": Uncaught exception!" )
3535 main.cleanup()
3536 main.exit()
3537
Jon Hallbd16b922015-03-26 17:53:15 -07003538 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003539 """
3540 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003541 appName is the hierarchical app name, not the feature name
3542 If check is True, method will check the status of the app after the
3543 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003544 Returns main.TRUE if the command was successfully sent
3545 main.FALSE if the cli responded with an error or given
3546 incorrect input
3547 """
3548 # TODO: check with Thomas about the state machine for apps
3549 try:
3550 if not isinstance( appName, types.StringType ):
3551 main.log.error( self.name + ".uninstallApp(): appName must " +
3552 "be a string" )
3553 return main.FALSE
3554 status = self.appStatus( appName )
3555 if status == "INSTALLED":
3556 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003557 if check and response == main.TRUE:
3558 for i in range(10): # try 10 times then give up
3559 status = self.appStatus( appName )
3560 if status == "UNINSTALLED":
3561 return main.TRUE
3562 else:
3563 time.sleep( 1 )
3564 return main.FALSE
3565 else: # not check or command didn't succeed
3566 return response
Jon Hall146f1522015-03-24 15:33:24 -07003567 elif status == "ACTIVE":
3568 main.log.warn( self.name + ": Tried to uninstall the " +
3569 "application '" + appName + "' which is " +
3570 "currently active." )
3571 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003572 if check and response == main.TRUE:
3573 for i in range(10): # try 10 times then give up
3574 status = self.appStatus( appName )
3575 if status == "UNINSTALLED":
3576 return main.TRUE
3577 else:
3578 time.sleep( 1 )
3579 return main.FALSE
3580 else: # not check or command didn't succeed
3581 return response
Jon Hall146f1522015-03-24 15:33:24 -07003582 elif status == "UNINSTALLED":
3583 return main.TRUE
3584 else:
3585 main.log.error( "Unexpected return value from appStatus: " +
3586 str( status ) )
3587 return main.ERROR
3588 except TypeError:
3589 main.log.exception( self.name + ": Object not as expected" )
3590 return main.ERROR
3591 except pexpect.EOF:
3592 main.log.error( self.name + ": EOF exception found" )
3593 main.log.error( self.name + ": " + self.handle.before )
3594 main.cleanup()
3595 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003596 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003597 main.log.exception( self.name + ": Uncaught exception!" )
3598 main.cleanup()
3599 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003600
3601 def appIDs( self, jsonFormat=True ):
3602 """
3603 Show the mappings between app id and app names given by the 'app-ids'
3604 cli command
3605 """
3606 try:
3607 cmdStr = "app-ids"
3608 if jsonFormat:
3609 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003610 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003611 assert "Command not found:" not in output, output
3612 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003613 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003614 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003615 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003616 return None
3617 except TypeError:
3618 main.log.exception( self.name + ": Object not as expected" )
3619 return None
3620 except pexpect.EOF:
3621 main.log.error( self.name + ": EOF exception found" )
3622 main.log.error( self.name + ": " + self.handle.before )
3623 main.cleanup()
3624 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003625 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003626 main.log.exception( self.name + ": Uncaught exception!" )
3627 main.cleanup()
3628 main.exit()
3629
3630 def appToIDCheck( self ):
3631 """
3632 This method will check that each application's ID listed in 'apps' is
3633 the same as the ID listed in 'app-ids'. The check will also check that
3634 there are no duplicate IDs issued. Note that an app ID should be
3635 a globaly unique numerical identifier for app/app-like features. Once
3636 an ID is registered, the ID is never freed up so that if an app is
3637 reinstalled it will have the same ID.
3638
3639 Returns: main.TRUE if the check passes and
3640 main.FALSE if the check fails or
3641 main.ERROR if there is some error in processing the test
3642 """
3643 try:
Jon Hall390696c2015-05-05 17:13:41 -07003644 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003645 rawJson = self.appIDs( jsonFormat=True )
3646 if rawJson:
3647 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003648 else:
Jon Hallc6793552016-01-19 14:18:37 -08003649 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003650 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003651 rawJson = self.apps( jsonFormat=True )
3652 if rawJson:
3653 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003654 else:
Jon Hallc6793552016-01-19 14:18:37 -08003655 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003656 bail = True
3657 if bail:
3658 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003659 result = main.TRUE
3660 for app in apps:
3661 appID = app.get( 'id' )
3662 if appID is None:
3663 main.log.error( "Error parsing app: " + str( app ) )
3664 result = main.FALSE
3665 appName = app.get( 'name' )
3666 if appName is None:
3667 main.log.error( "Error parsing app: " + str( app ) )
3668 result = main.FALSE
3669 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003670 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003671 # main.log.debug( "Comparing " + str( app ) + " to " +
3672 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003673 if not current: # if ids doesn't have this id
3674 result = main.FALSE
3675 main.log.error( "'app-ids' does not have the ID for " +
3676 str( appName ) + " that apps does." )
3677 elif len( current ) > 1:
3678 # there is more than one app with this ID
3679 result = main.FALSE
3680 # We will log this later in the method
3681 elif not current[0][ 'name' ] == appName:
3682 currentName = current[0][ 'name' ]
3683 result = main.FALSE
3684 main.log.error( "'app-ids' has " + str( currentName ) +
3685 " registered under id:" + str( appID ) +
3686 " but 'apps' has " + str( appName ) )
3687 else:
3688 pass # id and name match!
3689 # now make sure that app-ids has no duplicates
3690 idsList = []
3691 namesList = []
3692 for item in ids:
3693 idsList.append( item[ 'id' ] )
3694 namesList.append( item[ 'name' ] )
3695 if len( idsList ) != len( set( idsList ) ) or\
3696 len( namesList ) != len( set( namesList ) ):
3697 main.log.error( "'app-ids' has some duplicate entries: \n"
3698 + json.dumps( ids,
3699 sort_keys=True,
3700 indent=4,
3701 separators=( ',', ': ' ) ) )
3702 result = main.FALSE
3703 return result
Jon Hallc6793552016-01-19 14:18:37 -08003704 except ( TypeError, ValueError ):
3705 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003706 return main.ERROR
3707 except pexpect.EOF:
3708 main.log.error( self.name + ": EOF exception found" )
3709 main.log.error( self.name + ": " + self.handle.before )
3710 main.cleanup()
3711 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003712 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003713 main.log.exception( self.name + ": Uncaught exception!" )
3714 main.cleanup()
3715 main.exit()
3716
Jon Hallfb760a02015-04-13 15:35:03 -07003717 def getCfg( self, component=None, propName=None, short=False,
3718 jsonFormat=True ):
3719 """
3720 Get configuration settings from onos cli
3721 Optional arguments:
3722 component - Optionally only list configurations for a specific
3723 component. If None, all components with configurations
3724 are displayed. Case Sensitive string.
3725 propName - If component is specified, propName option will show
3726 only this specific configuration from that component.
3727 Case Sensitive string.
3728 jsonFormat - Returns output as json. Note that this will override
3729 the short option
3730 short - Short, less verbose, version of configurations.
3731 This is overridden by the json option
3732 returns:
3733 Output from cli as a string or None on error
3734 """
3735 try:
3736 baseStr = "cfg"
3737 cmdStr = " get"
3738 componentStr = ""
3739 if component:
3740 componentStr += " " + component
3741 if propName:
3742 componentStr += " " + propName
3743 if jsonFormat:
3744 baseStr += " -j"
3745 elif short:
3746 baseStr += " -s"
3747 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Hallc6793552016-01-19 14:18:37 -08003748 assert "Command not found:" not in output, output
3749 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003750 return output
3751 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003752 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003753 return None
3754 except TypeError:
3755 main.log.exception( self.name + ": Object not as expected" )
3756 return None
3757 except pexpect.EOF:
3758 main.log.error( self.name + ": EOF exception found" )
3759 main.log.error( self.name + ": " + self.handle.before )
3760 main.cleanup()
3761 main.exit()
3762 except Exception:
3763 main.log.exception( self.name + ": Uncaught exception!" )
3764 main.cleanup()
3765 main.exit()
3766
3767 def setCfg( self, component, propName, value=None, check=True ):
3768 """
3769 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003770 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003771 component - The case sensitive name of the component whose
3772 property is to be set
3773 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003774 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003775 value - The value to set the property to. If None, will unset the
3776 property and revert it to it's default value(if applicable)
3777 check - Boolean, Check whether the option was successfully set this
3778 only applies when a value is given.
3779 returns:
3780 main.TRUE on success or main.FALSE on failure. If check is False,
3781 will return main.TRUE unless there is an error
3782 """
3783 try:
3784 baseStr = "cfg"
3785 cmdStr = " set " + str( component ) + " " + str( propName )
3786 if value is not None:
3787 cmdStr += " " + str( value )
3788 output = self.sendline( baseStr + cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003789 assert "Command not found:" not in output, output
3790 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003791 if value and check:
3792 results = self.getCfg( component=str( component ),
3793 propName=str( propName ),
3794 jsonFormat=True )
3795 # Check if current value is what we just set
3796 try:
3797 jsonOutput = json.loads( results )
3798 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003799 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003800 main.log.exception( "Error parsing cfg output" )
3801 main.log.error( "output:" + repr( results ) )
3802 return main.FALSE
3803 if current == str( value ):
3804 return main.TRUE
3805 return main.FALSE
3806 return main.TRUE
3807 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003808 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003809 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003810 except ( TypeError, ValueError ):
3811 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003812 return main.FALSE
3813 except pexpect.EOF:
3814 main.log.error( self.name + ": EOF exception found" )
3815 main.log.error( self.name + ": " + self.handle.before )
3816 main.cleanup()
3817 main.exit()
3818 except Exception:
3819 main.log.exception( self.name + ": Uncaught exception!" )
3820 main.cleanup()
3821 main.exit()
3822
Jon Hall390696c2015-05-05 17:13:41 -07003823 def setTestAdd( self, setName, values ):
3824 """
3825 CLI command to add elements to a distributed set.
3826 Arguments:
3827 setName - The name of the set to add to.
3828 values - The value(s) to add to the set, space seperated.
3829 Example usages:
3830 setTestAdd( "set1", "a b c" )
3831 setTestAdd( "set2", "1" )
3832 returns:
3833 main.TRUE on success OR
3834 main.FALSE if elements were already in the set OR
3835 main.ERROR on error
3836 """
3837 try:
3838 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3839 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003840 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003841 try:
3842 # TODO: Maybe make this less hardcoded
3843 # ConsistentMap Exceptions
3844 assert "org.onosproject.store.service" not in output
3845 # Node not leader
3846 assert "java.lang.IllegalStateException" not in output
3847 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003848 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003849 "command: " + str( output ) )
3850 retryTime = 30 # Conservative time, given by Madan
3851 main.log.info( "Waiting " + str( retryTime ) +
3852 "seconds before retrying." )
3853 time.sleep( retryTime ) # Due to change in mastership
3854 output = self.sendline( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003855 assert "Error executing command" not in output
3856 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3857 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3858 main.log.info( self.name + ": " + output )
3859 if re.search( positiveMatch, output):
3860 return main.TRUE
3861 elif re.search( negativeMatch, output):
3862 return main.FALSE
3863 else:
3864 main.log.error( self.name + ": setTestAdd did not" +
3865 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003866 main.log.debug( self.name + " actual: " + repr( output ) )
3867 return main.ERROR
3868 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003869 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003870 return main.ERROR
3871 except TypeError:
3872 main.log.exception( self.name + ": Object not as expected" )
3873 return main.ERROR
3874 except pexpect.EOF:
3875 main.log.error( self.name + ": EOF exception found" )
3876 main.log.error( self.name + ": " + self.handle.before )
3877 main.cleanup()
3878 main.exit()
3879 except Exception:
3880 main.log.exception( self.name + ": Uncaught exception!" )
3881 main.cleanup()
3882 main.exit()
3883
3884 def setTestRemove( self, setName, values, clear=False, retain=False ):
3885 """
3886 CLI command to remove elements from a distributed set.
3887 Required arguments:
3888 setName - The name of the set to remove from.
3889 values - The value(s) to remove from the set, space seperated.
3890 Optional arguments:
3891 clear - Clear all elements from the set
3892 retain - Retain only the given values. (intersection of the
3893 original set and the given set)
3894 returns:
3895 main.TRUE on success OR
3896 main.FALSE if the set was not changed OR
3897 main.ERROR on error
3898 """
3899 try:
3900 cmdStr = "set-test-remove "
3901 if clear:
3902 cmdStr += "-c " + str( setName )
3903 elif retain:
3904 cmdStr += "-r " + str( setName ) + " " + str( values )
3905 else:
3906 cmdStr += str( setName ) + " " + str( values )
3907 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003908 try:
3909 # TODO: Maybe make this less hardcoded
3910 # ConsistentMap Exceptions
3911 assert "org.onosproject.store.service" not in output
3912 # Node not leader
3913 assert "java.lang.IllegalStateException" not in output
3914 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003915 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003916 "command: " + str( output ) )
3917 retryTime = 30 # Conservative time, given by Madan
3918 main.log.info( "Waiting " + str( retryTime ) +
3919 "seconds before retrying." )
3920 time.sleep( retryTime ) # Due to change in mastership
3921 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003922 assert "Command not found:" not in output, output
3923 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003924 main.log.info( self.name + ": " + output )
3925 if clear:
3926 pattern = "Set " + str( setName ) + " cleared"
3927 if re.search( pattern, output ):
3928 return main.TRUE
3929 elif retain:
3930 positivePattern = str( setName ) + " was pruned to contain " +\
3931 "only elements of set \[(.*)\]"
3932 negativePattern = str( setName ) + " was not changed by " +\
3933 "retaining only elements of the set " +\
3934 "\[(.*)\]"
3935 if re.search( positivePattern, output ):
3936 return main.TRUE
3937 elif re.search( negativePattern, output ):
3938 return main.FALSE
3939 else:
3940 positivePattern = "\[(.*)\] was removed from the set " +\
3941 str( setName )
3942 if ( len( values.split() ) == 1 ):
3943 negativePattern = "\[(.*)\] was not in set " +\
3944 str( setName )
3945 else:
3946 negativePattern = "No element of \[(.*)\] was in set " +\
3947 str( setName )
3948 if re.search( positivePattern, output ):
3949 return main.TRUE
3950 elif re.search( negativePattern, output ):
3951 return main.FALSE
3952 main.log.error( self.name + ": setTestRemove did not" +
3953 " match expected output" )
3954 main.log.debug( self.name + " expected: " + pattern )
3955 main.log.debug( self.name + " actual: " + repr( output ) )
3956 return main.ERROR
3957 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003958 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07003959 return main.ERROR
3960 except TypeError:
3961 main.log.exception( self.name + ": Object not as expected" )
3962 return main.ERROR
3963 except pexpect.EOF:
3964 main.log.error( self.name + ": EOF exception found" )
3965 main.log.error( self.name + ": " + self.handle.before )
3966 main.cleanup()
3967 main.exit()
3968 except Exception:
3969 main.log.exception( self.name + ": Uncaught exception!" )
3970 main.cleanup()
3971 main.exit()
3972
3973 def setTestGet( self, setName, values="" ):
3974 """
3975 CLI command to get the elements in a distributed set.
3976 Required arguments:
3977 setName - The name of the set to remove from.
3978 Optional arguments:
3979 values - The value(s) to check if in the set, space seperated.
3980 returns:
3981 main.ERROR on error OR
3982 A list of elements in the set if no optional arguments are
3983 supplied OR
3984 A tuple containing the list then:
3985 main.FALSE if the given values are not in the set OR
3986 main.TRUE if the given values are in the set OR
3987 """
3988 try:
3989 values = str( values ).strip()
3990 setName = str( setName ).strip()
3991 length = len( values.split() )
3992 containsCheck = None
3993 # Patterns to match
3994 setPattern = "\[(.*)\]"
3995 pattern = "Items in set " + setName + ":\n" + setPattern
3996 containsTrue = "Set " + setName + " contains the value " + values
3997 containsFalse = "Set " + setName + " did not contain the value " +\
3998 values
3999 containsAllTrue = "Set " + setName + " contains the the subset " +\
4000 setPattern
4001 containsAllFalse = "Set " + setName + " did not contain the the" +\
4002 " subset " + setPattern
4003
4004 cmdStr = "set-test-get "
4005 cmdStr += setName + " " + values
4006 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004007 try:
4008 # TODO: Maybe make this less hardcoded
4009 # ConsistentMap Exceptions
4010 assert "org.onosproject.store.service" not in output
4011 # Node not leader
4012 assert "java.lang.IllegalStateException" not in output
4013 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004014 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004015 "command: " + str( output ) )
4016 retryTime = 30 # Conservative time, given by Madan
4017 main.log.info( "Waiting " + str( retryTime ) +
4018 "seconds before retrying." )
4019 time.sleep( retryTime ) # Due to change in mastership
4020 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004021 assert "Command not found:" not in output, output
4022 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004023 main.log.info( self.name + ": " + output )
4024
4025 if length == 0:
4026 match = re.search( pattern, output )
4027 else: # if given values
4028 if length == 1: # Contains output
4029 patternTrue = pattern + "\n" + containsTrue
4030 patternFalse = pattern + "\n" + containsFalse
4031 else: # ContainsAll output
4032 patternTrue = pattern + "\n" + containsAllTrue
4033 patternFalse = pattern + "\n" + containsAllFalse
4034 matchTrue = re.search( patternTrue, output )
4035 matchFalse = re.search( patternFalse, output )
4036 if matchTrue:
4037 containsCheck = main.TRUE
4038 match = matchTrue
4039 elif matchFalse:
4040 containsCheck = main.FALSE
4041 match = matchFalse
4042 else:
4043 main.log.error( self.name + " setTestGet did not match " +\
4044 "expected output" )
4045 main.log.debug( self.name + " expected: " + pattern )
4046 main.log.debug( self.name + " actual: " + repr( output ) )
4047 match = None
4048 if match:
4049 setMatch = match.group( 1 )
4050 if setMatch == '':
4051 setList = []
4052 else:
4053 setList = setMatch.split( ", " )
4054 if length > 0:
4055 return ( setList, containsCheck )
4056 else:
4057 return setList
4058 else: # no match
4059 main.log.error( self.name + ": setTestGet did not" +
4060 " match expected output" )
4061 main.log.debug( self.name + " expected: " + pattern )
4062 main.log.debug( self.name + " actual: " + repr( output ) )
4063 return main.ERROR
4064 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004065 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004066 return main.ERROR
4067 except TypeError:
4068 main.log.exception( self.name + ": Object not as expected" )
4069 return main.ERROR
4070 except pexpect.EOF:
4071 main.log.error( self.name + ": EOF exception found" )
4072 main.log.error( self.name + ": " + self.handle.before )
4073 main.cleanup()
4074 main.exit()
4075 except Exception:
4076 main.log.exception( self.name + ": Uncaught exception!" )
4077 main.cleanup()
4078 main.exit()
4079
4080 def setTestSize( self, setName ):
4081 """
4082 CLI command to get the elements in a distributed set.
4083 Required arguments:
4084 setName - The name of the set to remove from.
4085 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004086 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004087 None on error
4088 """
4089 try:
4090 # TODO: Should this check against the number of elements returned
4091 # and then return true/false based on that?
4092 setName = str( setName ).strip()
4093 # Patterns to match
4094 setPattern = "\[(.*)\]"
4095 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4096 setPattern
4097 cmdStr = "set-test-get -s "
4098 cmdStr += setName
4099 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004100 try:
4101 # TODO: Maybe make this less hardcoded
4102 # ConsistentMap Exceptions
4103 assert "org.onosproject.store.service" not in output
4104 # Node not leader
4105 assert "java.lang.IllegalStateException" not in output
4106 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004107 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004108 "command: " + str( output ) )
4109 retryTime = 30 # Conservative time, given by Madan
4110 main.log.info( "Waiting " + str( retryTime ) +
4111 "seconds before retrying." )
4112 time.sleep( retryTime ) # Due to change in mastership
4113 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004114 assert "Command not found:" not in output, output
4115 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004116 main.log.info( self.name + ": " + output )
4117 match = re.search( pattern, output )
4118 if match:
4119 setSize = int( match.group( 1 ) )
4120 setMatch = match.group( 2 )
4121 if len( setMatch.split() ) == setSize:
4122 main.log.info( "The size returned by " + self.name +
4123 " matches the number of elements in " +
4124 "the returned set" )
4125 else:
4126 main.log.error( "The size returned by " + self.name +
4127 " does not match the number of " +
4128 "elements in the returned set." )
4129 return setSize
4130 else: # no match
4131 main.log.error( self.name + ": setTestGet did not" +
4132 " match expected output" )
4133 main.log.debug( self.name + " expected: " + pattern )
4134 main.log.debug( self.name + " actual: " + repr( output ) )
4135 return None
4136 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004137 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004138 return None
Jon Hall390696c2015-05-05 17:13:41 -07004139 except TypeError:
4140 main.log.exception( self.name + ": Object not as expected" )
4141 return None
4142 except pexpect.EOF:
4143 main.log.error( self.name + ": EOF exception found" )
4144 main.log.error( self.name + ": " + self.handle.before )
4145 main.cleanup()
4146 main.exit()
4147 except Exception:
4148 main.log.exception( self.name + ": Uncaught exception!" )
4149 main.cleanup()
4150 main.exit()
4151
Jon Hall80daded2015-05-27 16:07:00 -07004152 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004153 """
4154 Command to list the various counters in the system.
4155 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004156 if jsonFormat, a string of the json object returned by the cli
4157 command
4158 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004159 None on error
4160 """
Jon Hall390696c2015-05-05 17:13:41 -07004161 try:
4162 counters = {}
4163 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004164 if jsonFormat:
4165 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004166 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004167 assert "Command not found:" not in output, output
4168 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004169 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004170 return output
Jon Hall390696c2015-05-05 17:13:41 -07004171 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004172 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004173 return None
Jon Hall390696c2015-05-05 17:13:41 -07004174 except TypeError:
4175 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004176 return None
Jon Hall390696c2015-05-05 17:13:41 -07004177 except pexpect.EOF:
4178 main.log.error( self.name + ": EOF exception found" )
4179 main.log.error( self.name + ": " + self.handle.before )
4180 main.cleanup()
4181 main.exit()
4182 except Exception:
4183 main.log.exception( self.name + ": Uncaught exception!" )
4184 main.cleanup()
4185 main.exit()
4186
Jon Hall935db192016-04-19 00:22:04 -07004187 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004188 """
Jon Halle1a3b752015-07-22 13:02:46 -07004189 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004190 Required arguments:
4191 counter - The name of the counter to increment.
4192 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004193 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004194 returns:
4195 integer value of the counter or
4196 None on Error
4197 """
4198 try:
4199 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004200 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004201 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004202 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004203 if delta != 1:
4204 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004205 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004206 try:
4207 # TODO: Maybe make this less hardcoded
4208 # ConsistentMap Exceptions
4209 assert "org.onosproject.store.service" not in output
4210 # Node not leader
4211 assert "java.lang.IllegalStateException" not in output
4212 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004213 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004214 "command: " + str( output ) )
4215 retryTime = 30 # Conservative time, given by Madan
4216 main.log.info( "Waiting " + str( retryTime ) +
4217 "seconds before retrying." )
4218 time.sleep( retryTime ) # Due to change in mastership
4219 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004220 assert "Command not found:" not in output, output
4221 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004222 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004223 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004224 match = re.search( pattern, output )
4225 if match:
4226 return int( match.group( 1 ) )
4227 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004228 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004229 " match expected output." )
4230 main.log.debug( self.name + " expected: " + pattern )
4231 main.log.debug( self.name + " actual: " + repr( output ) )
4232 return None
4233 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004234 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004235 return None
4236 except TypeError:
4237 main.log.exception( self.name + ": Object not as expected" )
4238 return None
4239 except pexpect.EOF:
4240 main.log.error( self.name + ": EOF exception found" )
4241 main.log.error( self.name + ": " + self.handle.before )
4242 main.cleanup()
4243 main.exit()
4244 except Exception:
4245 main.log.exception( self.name + ": Uncaught exception!" )
4246 main.cleanup()
4247 main.exit()
4248
Jon Hall935db192016-04-19 00:22:04 -07004249 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004250 """
4251 CLI command to get a distributed counter then add a delta to it.
4252 Required arguments:
4253 counter - The name of the counter to increment.
4254 Optional arguments:
4255 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004256 returns:
4257 integer value of the counter or
4258 None on Error
4259 """
4260 try:
4261 counter = str( counter )
4262 delta = int( delta )
4263 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004264 cmdStr += counter
4265 if delta != 1:
4266 cmdStr += " " + str( delta )
4267 output = self.sendline( cmdStr )
4268 try:
4269 # TODO: Maybe make this less hardcoded
4270 # ConsistentMap Exceptions
4271 assert "org.onosproject.store.service" not in output
4272 # Node not leader
4273 assert "java.lang.IllegalStateException" not in output
4274 except AssertionError:
4275 main.log.error( "Error in processing '" + cmdStr + "' " +
4276 "command: " + str( output ) )
4277 retryTime = 30 # Conservative time, given by Madan
4278 main.log.info( "Waiting " + str( retryTime ) +
4279 "seconds before retrying." )
4280 time.sleep( retryTime ) # Due to change in mastership
4281 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004282 assert "Command not found:" not in output, output
4283 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004284 main.log.info( self.name + ": " + output )
4285 pattern = counter + " was updated to (-?\d+)"
4286 match = re.search( pattern, output )
4287 if match:
4288 return int( match.group( 1 ) )
4289 else:
4290 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4291 " match expected output." )
4292 main.log.debug( self.name + " expected: " + pattern )
4293 main.log.debug( self.name + " actual: " + repr( output ) )
4294 return None
4295 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004296 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004297 return None
4298 except TypeError:
4299 main.log.exception( self.name + ": Object not as expected" )
4300 return None
4301 except pexpect.EOF:
4302 main.log.error( self.name + ": EOF exception found" )
4303 main.log.error( self.name + ": " + self.handle.before )
4304 main.cleanup()
4305 main.exit()
4306 except Exception:
4307 main.log.exception( self.name + ": Uncaught exception!" )
4308 main.cleanup()
4309 main.exit()
4310
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004311 def summary( self, jsonFormat=True ):
4312 """
4313 Description: Execute summary command in onos
4314 Returns: json object ( summary -j ), returns main.FALSE if there is
4315 no output
4316
4317 """
4318 try:
4319 cmdStr = "summary"
4320 if jsonFormat:
4321 cmdStr += " -j"
4322 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004323 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004324 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004325 if not handle:
4326 main.log.error( self.name + ": There is no output in " +
4327 "summary command" )
4328 return main.FALSE
4329 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004330 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004331 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004332 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004333 except TypeError:
4334 main.log.exception( self.name + ": Object not as expected" )
4335 return None
4336 except pexpect.EOF:
4337 main.log.error( self.name + ": EOF exception found" )
4338 main.log.error( self.name + ": " + self.handle.before )
4339 main.cleanup()
4340 main.exit()
4341 except Exception:
4342 main.log.exception( self.name + ": Uncaught exception!" )
4343 main.cleanup()
4344 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004345
Jon Hall935db192016-04-19 00:22:04 -07004346 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004347 """
4348 CLI command to get the value of a key in a consistent map using
4349 transactions. This a test function and can only get keys from the
4350 test map hard coded into the cli command
4351 Required arguments:
4352 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004353 returns:
4354 The string value of the key or
4355 None on Error
4356 """
4357 try:
4358 keyName = str( keyName )
4359 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004360 cmdStr += keyName
4361 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004362 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004363 try:
4364 # TODO: Maybe make this less hardcoded
4365 # ConsistentMap Exceptions
4366 assert "org.onosproject.store.service" not in output
4367 # Node not leader
4368 assert "java.lang.IllegalStateException" not in output
4369 except AssertionError:
4370 main.log.error( "Error in processing '" + cmdStr + "' " +
4371 "command: " + str( output ) )
4372 return None
4373 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4374 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004375 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004376 return None
4377 else:
4378 match = re.search( pattern, output )
4379 if match:
4380 return match.groupdict()[ 'value' ]
4381 else:
4382 main.log.error( self.name + ": transactionlMapGet did not" +
4383 " match expected output." )
4384 main.log.debug( self.name + " expected: " + pattern )
4385 main.log.debug( self.name + " actual: " + repr( output ) )
4386 return None
Jon Hallc6793552016-01-19 14:18:37 -08004387 except AssertionError:
4388 main.log.exception( "" )
4389 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004390 except TypeError:
4391 main.log.exception( self.name + ": Object not as expected" )
4392 return None
4393 except pexpect.EOF:
4394 main.log.error( self.name + ": EOF exception found" )
4395 main.log.error( self.name + ": " + self.handle.before )
4396 main.cleanup()
4397 main.exit()
4398 except Exception:
4399 main.log.exception( self.name + ": Uncaught exception!" )
4400 main.cleanup()
4401 main.exit()
4402
Jon Hall935db192016-04-19 00:22:04 -07004403 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004404 """
4405 CLI command to put a value into 'numKeys' number of keys in a
4406 consistent map using transactions. This a test function and can only
4407 put into keys named 'Key#' of the test map hard coded into the cli command
4408 Required arguments:
4409 numKeys - Number of keys to add the value to
4410 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004411 returns:
4412 A dictionary whose keys are the name of the keys put into the map
4413 and the values of the keys are dictionaries whose key-values are
4414 'value': value put into map and optionaly
4415 'oldValue': Previous value in the key or
4416 None on Error
4417
4418 Example output
4419 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4420 'Key2': {'value': 'Testing'} }
4421 """
4422 try:
4423 numKeys = str( numKeys )
4424 value = str( value )
4425 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004426 cmdStr += numKeys + " " + value
4427 output = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004428 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004429 try:
4430 # TODO: Maybe make this less hardcoded
4431 # ConsistentMap Exceptions
4432 assert "org.onosproject.store.service" not in output
4433 # Node not leader
4434 assert "java.lang.IllegalStateException" not in output
4435 except AssertionError:
4436 main.log.error( "Error in processing '" + cmdStr + "' " +
4437 "command: " + str( output ) )
4438 return None
4439 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4440 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4441 results = {}
4442 for line in output.splitlines():
4443 new = re.search( newPattern, line )
4444 updated = re.search( updatedPattern, line )
4445 if new:
4446 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4447 elif updated:
4448 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004449 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004450 else:
4451 main.log.error( self.name + ": transactionlMapGet did not" +
4452 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004453 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4454 newPattern,
4455 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004456 main.log.debug( self.name + " actual: " + repr( output ) )
4457 return results
Jon Hallc6793552016-01-19 14:18:37 -08004458 except AssertionError:
4459 main.log.exception( "" )
4460 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004461 except TypeError:
4462 main.log.exception( self.name + ": Object not as expected" )
4463 return None
4464 except pexpect.EOF:
4465 main.log.error( self.name + ": EOF exception found" )
4466 main.log.error( self.name + ": " + self.handle.before )
4467 main.cleanup()
4468 main.exit()
4469 except Exception:
4470 main.log.exception( self.name + ": Uncaught exception!" )
4471 main.cleanup()
4472 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004473
acsmarsdaea66c2015-09-03 11:44:06 -07004474 def maps( self, jsonFormat=True ):
4475 """
4476 Description: Returns result of onos:maps
4477 Optional:
4478 * jsonFormat: enable json formatting of output
4479 """
4480 try:
4481 cmdStr = "maps"
4482 if jsonFormat:
4483 cmdStr += " -j"
4484 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08004485 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004486 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004487 except AssertionError:
4488 main.log.exception( "" )
4489 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004490 except TypeError:
4491 main.log.exception( self.name + ": Object not as expected" )
4492 return None
4493 except pexpect.EOF:
4494 main.log.error( self.name + ": EOF exception found" )
4495 main.log.error( self.name + ": " + self.handle.before )
4496 main.cleanup()
4497 main.exit()
4498 except Exception:
4499 main.log.exception( self.name + ": Uncaught exception!" )
4500 main.cleanup()
4501 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004502
4503 def getSwController( self, uri, jsonFormat=True ):
4504 """
4505 Descrition: Gets the controller information from the device
4506 """
4507 try:
4508 cmd = "device-controllers "
4509 if jsonFormat:
4510 cmd += "-j "
4511 response = self.sendline( cmd + uri )
Jon Hallc6793552016-01-19 14:18:37 -08004512 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004513 return response
Jon Hallc6793552016-01-19 14:18:37 -08004514 except AssertionError:
4515 main.log.exception( "" )
4516 return None
GlennRC050596c2015-11-18 17:06:41 -08004517 except TypeError:
4518 main.log.exception( self.name + ": Object not as expected" )
4519 return None
4520 except pexpect.EOF:
4521 main.log.error( self.name + ": EOF exception found" )
4522 main.log.error( self.name + ": " + self.handle.before )
4523 main.cleanup()
4524 main.exit()
4525 except Exception:
4526 main.log.exception( self.name + ": Uncaught exception!" )
4527 main.cleanup()
4528 main.exit()
4529
4530 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4531 """
4532 Descrition: sets the controller(s) for the specified device
4533
4534 Parameters:
4535 Required: uri - String: The uri of the device(switch).
4536 ip - String or List: The ip address of the controller.
4537 This parameter can be formed in a couple of different ways.
4538 VALID:
4539 10.0.0.1 - just the ip address
4540 tcp:10.0.0.1 - the protocol and the ip address
4541 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4542 so that you can add controllers with different
4543 protocols and ports
4544 INVALID:
4545 10.0.0.1:6653 - this is not supported by ONOS
4546
4547 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4548 port - The port number.
4549 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4550
4551 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4552 """
4553 try:
4554 cmd = "device-setcontrollers"
4555
4556 if jsonFormat:
4557 cmd += " -j"
4558 cmd += " " + uri
4559 if isinstance( ip, str ):
4560 ip = [ip]
4561 for item in ip:
4562 if ":" in item:
4563 sitem = item.split( ":" )
4564 if len(sitem) == 3:
4565 cmd += " " + item
4566 elif "." in sitem[1]:
4567 cmd += " {}:{}".format(item, port)
4568 else:
4569 main.log.error( "Malformed entry: " + item )
4570 raise TypeError
4571 else:
4572 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004573 response = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08004574 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004575 if "Error" in response:
4576 main.log.error( response )
4577 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004578 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004579 except AssertionError:
4580 main.log.exception( "" )
4581 return None
GlennRC050596c2015-11-18 17:06:41 -08004582 except TypeError:
4583 main.log.exception( self.name + ": Object not as expected" )
4584 return main.FALSE
4585 except pexpect.EOF:
4586 main.log.error( self.name + ": EOF exception found" )
4587 main.log.error( self.name + ": " + self.handle.before )
4588 main.cleanup()
4589 main.exit()
4590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
4592 main.cleanup()
4593 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004594
4595 def removeDevice( self, device ):
4596 '''
4597 Description:
4598 Remove a device from ONOS by passing the uri of the device(s).
4599 Parameters:
4600 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4601 Returns:
4602 Returns main.FALSE if an exception is thrown or an error is present
4603 in the response. Otherwise, returns main.TRUE.
4604 NOTE:
4605 If a host cannot be removed, then this function will return main.FALSE
4606 '''
4607 try:
4608 if type( device ) is str:
4609 device = list( device )
4610
4611 for d in device:
4612 time.sleep( 1 )
4613 response = self.sendline( "device-remove {}".format( d ) )
Jon Hallc6793552016-01-19 14:18:37 -08004614 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004615 if "Error" in response:
4616 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4617 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004618 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004619 except AssertionError:
4620 main.log.exception( "" )
4621 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004622 except TypeError:
4623 main.log.exception( self.name + ": Object not as expected" )
4624 return main.FALSE
4625 except pexpect.EOF:
4626 main.log.error( self.name + ": EOF exception found" )
4627 main.log.error( self.name + ": " + self.handle.before )
4628 main.cleanup()
4629 main.exit()
4630 except Exception:
4631 main.log.exception( self.name + ": Uncaught exception!" )
4632 main.cleanup()
4633 main.exit()
4634
4635 def removeHost( self, host ):
4636 '''
4637 Description:
4638 Remove a host from ONOS by passing the id of the host(s)
4639 Parameters:
4640 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4641 Returns:
4642 Returns main.FALSE if an exception is thrown or an error is present
4643 in the response. Otherwise, returns main.TRUE.
4644 NOTE:
4645 If a host cannot be removed, then this function will return main.FALSE
4646 '''
4647 try:
4648 if type( host ) is str:
4649 host = list( host )
4650
4651 for h in host:
4652 time.sleep( 1 )
4653 response = self.sendline( "host-remove {}".format( h ) )
Jon Hallc6793552016-01-19 14:18:37 -08004654 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004655 if "Error" in response:
4656 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4657 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004658 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004659 except AssertionError:
4660 main.log.exception( "" )
4661 return None
GlennRC20fc6522015-12-23 23:26:57 -08004662 except TypeError:
4663 main.log.exception( self.name + ": Object not as expected" )
4664 return main.FALSE
4665 except pexpect.EOF:
4666 main.log.error( self.name + ": EOF exception found" )
4667 main.log.error( self.name + ": " + self.handle.before )
4668 main.cleanup()
4669 main.exit()
4670 except Exception:
4671 main.log.exception( self.name + ": Uncaught exception!" )
4672 main.cleanup()
4673 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004674
Jon Hallc6793552016-01-19 14:18:37 -08004675 def link( self, begin, end, state ):
GlennRCed771242016-01-13 17:02:47 -08004676 '''
4677 Description:
4678 Bring link down or up in the null-provider.
4679 params:
4680 begin - (string) One end of a device or switch.
4681 end - (string) the other end of the device or switch
4682 returns:
4683 main.TRUE if no exceptions were thrown and no Errors are
4684 present in the resoponse. Otherwise, returns main.FALSE
4685 '''
4686 try:
Jon Hallc6793552016-01-19 14:18:37 -08004687 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
GlennRCed771242016-01-13 17:02:47 -08004688 response = self.sendline( cmd, showResponse=True )
Jon Hallc6793552016-01-19 14:18:37 -08004689 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004690 if "Error" in response or "Failure" in response:
4691 main.log.error( response )
4692 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004693 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004694 except AssertionError:
4695 main.log.exception( "" )
4696 return None
GlennRCed771242016-01-13 17:02:47 -08004697 except TypeError:
4698 main.log.exception( self.name + ": Object not as expected" )
4699 return main.FALSE
4700 except pexpect.EOF:
4701 main.log.error( self.name + ": EOF exception found" )
4702 main.log.error( self.name + ": " + self.handle.before )
4703 main.cleanup()
4704 main.exit()
4705 except Exception:
4706 main.log.exception( self.name + ": Uncaught exception!" )
4707 main.cleanup()
4708 main.exit()
4709