blob: eea502bb64ea2153bd06c8009fcb632266f506d3 [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
Jeremy Songsterae01bba2016-07-11 15:39:17 -070017Modified 2016 by ON.Lab
18
19Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
20the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
21or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
andrewonlab95ce8322014-10-13 14:12:04 -040022
kelvin8ec71442015-01-15 16:57:00 -080023"""
andrewonlab95ce8322014-10-13 14:12:04 -040024import pexpect
25import re
Jon Hall30b82fa2015-03-04 17:15:43 -080026import json
27import types
Jon Hallbd16b922015-03-26 17:53:15 -070028import time
kelvin-onlaba4074292015-07-09 15:19:49 -070029import os
andrewonlab95ce8322014-10-13 14:12:04 -040030from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070031from core.graph import Graph
andrewonlab95ce8322014-10-13 14:12:04 -040032
andrewonlab95ce8322014-10-13 14:12:04 -040033
kelvin8ec71442015-01-15 16:57:00 -080034class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040035
kelvin8ec71442015-01-15 16:57:00 -080036 def __init__( self ):
37 """
38 Initialize client
39 """
Jon Hallefbd9792015-03-05 16:11:36 -080040 self.name = None
41 self.home = None
42 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070043 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080044 super( CLI, self ).__init__()
45
46 def connect( self, **connectargs ):
47 """
andrewonlab95ce8322014-10-13 14:12:04 -040048 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080049 """
andrewonlab95ce8322014-10-13 14:12:04 -040050 try:
51 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080052 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070053 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040054 for key in self.options:
55 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080056 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040057 break
kelvin-onlabfb521662015-02-27 09:52:40 -080058 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070059 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040060
kelvin-onlaba4074292015-07-09 15:19:49 -070061 for key in self.options:
62 if key == 'onosIp':
63 self.onosIp = self.options[ 'onosIp' ]
64 break
65
kelvin8ec71442015-01-15 16:57:00 -080066 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070067
68 try:
Jon Hallc6793552016-01-19 14:18:37 -080069 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070070 self.ip_address = os.getenv( str( self.ip_address ) )
71 else:
72 main.log.info( self.name +
73 ": Trying to connect to " +
74 self.ip_address )
75
76 except KeyError:
77 main.log.info( "Invalid host name," +
78 " connecting to local host instead" )
79 self.ip_address = 'localhost'
80 except Exception as inst:
81 main.log.error( "Uncaught exception: " + str( inst ) )
82
kelvin8ec71442015-01-15 16:57:00 -080083 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080084 user_name=self.user_name,
85 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080086 port=self.port,
87 pwd=self.pwd,
88 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin8ec71442015-01-15 16:57:00 -080090 self.handle.sendline( "cd " + self.home )
91 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040092 if self.handle:
93 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080094 else:
95 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040096 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080097 except TypeError:
98 main.log.exception( self.name + ": Object not as expected" )
99 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800101 main.log.error( self.name + ": EOF exception found" )
102 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400103 main.cleanup()
104 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800106 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400107 main.cleanup()
108 main.exit()
109
kelvin8ec71442015-01-15 16:57:00 -0800110 def disconnect( self ):
111 """
andrewonlab95ce8322014-10-13 14:12:04 -0400112 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800113 """
Jon Halld61331b2015-02-17 16:35:47 -0800114 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400115 try:
Jon Hall61282e32015-03-19 11:34:11 -0700116 if self.handle:
117 i = self.logout()
118 if i == main.TRUE:
119 self.handle.sendline( "" )
120 self.handle.expect( "\$" )
121 self.handle.sendline( "exit" )
122 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800125 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700129 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700130 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700131 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400134 response = main.FALSE
135 return response
136
kelvin8ec71442015-01-15 16:57:00 -0800137 def logout( self ):
138 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500139 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700140 Returns main.TRUE if exited CLI and
141 main.FALSE on timeout (not guranteed you are disconnected)
142 None on TypeError
143 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800144 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500145 try:
Jon Hall61282e32015-03-19 11:34:11 -0700146 if self.handle:
147 self.handle.sendline( "" )
148 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
149 timeout=10 )
150 if i == 0: # In ONOS CLI
151 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700152 j = self.handle.expect( [ "\$",
153 "Command not found:",
154 pexpect.TIMEOUT ] )
155 if j == 0: # Successfully logged out
156 return main.TRUE
157 elif j == 1 or j == 2:
158 # ONOS didn't fully load, and logout command isn't working
159 # or the command timed out
160 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700161 try:
162 self.handle.expect( "\$" )
163 except pexpect.TIMEOUT:
164 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700165 return main.TRUE
166 else: # some other output
167 main.log.warn( "Unknown repsonse to logout command: '{}'",
168 repr( self.handle.before ) )
169 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700170 elif i == 1: # not in CLI
171 return main.TRUE
172 elif i == 3: # Timeout
173 return main.FALSE
174 else:
andrewonlab9627f432014-11-14 12:45:10 -0500175 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800176 except TypeError:
177 main.log.exception( self.name + ": Object not as expected" )
178 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800180 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700181 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500182 main.cleanup()
183 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700184 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700185 main.log.error( self.name +
186 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800188 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500189 main.cleanup()
190 main.exit()
191
kelvin-onlabd3b64892015-01-20 13:26:24 -0800192 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800193 """
andrewonlab95ce8322014-10-13 14:12:04 -0400194 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800195
andrewonlab95ce8322014-10-13 14:12:04 -0400196 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800197 """
andrewonlab95ce8322014-10-13 14:12:04 -0400198 try:
199 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800200 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400201 main.cleanup()
202 main.exit()
203 else:
kelvin8ec71442015-01-15 16:57:00 -0800204 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800205 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800206 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400207 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800208 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800209 handleBefore = self.handle.before
210 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800211 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800212 self.handle.sendline("")
213 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800214 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 main.log.info( "Cell call returned: " + handleBefore +
217 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400218
219 return main.TRUE
220
Jon Halld4d4b372015-01-28 16:02:41 -0800221 except TypeError:
222 main.log.exception( self.name + ": Object not as expected" )
223 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( self.name + ": eof exception found" )
226 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400227 main.cleanup()
228 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800230 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400231 main.cleanup()
232 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800233
pingping-lin57a56ce2015-05-20 16:43:48 -0700234 def startOnosCli( self, ONOSIp, karafTimeout="",
Jon Hallc6793552016-01-19 14:18:37 -0800235 commandlineTimeout=10, onosStartTimeout=60 ):
kelvin8ec71442015-01-15 16:57:00 -0800236 """
Jon Hallefbd9792015-03-05 16:11:36 -0800237 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 by user would be used to set the current karaf shell idle timeout.
239 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800240 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800241 Below is an example to start a session with 60 seconds idle timeout
242 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800243
Hari Krishna25d42f72015-01-05 15:08:28 -0800244 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800245 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800246
kelvin-onlabd3b64892015-01-20 13:26:24 -0800247 Note: karafTimeout is left as str so that this could be read
248 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800249 """
You Wangf69ab392016-01-26 16:34:38 -0800250 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400251 try:
kelvin8ec71442015-01-15 16:57:00 -0800252 self.handle.sendline( "" )
253 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500255
256 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800257 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500258 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400259
kelvin8ec71442015-01-15 16:57:00 -0800260 # Wait for onos start ( -w ) and enter onos cli
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800262 i = self.handle.expect( [
263 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700264 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400265
266 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800268 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800269 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800270 "config:property-set -p org.apache.karaf.shell\
271 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800272 karafTimeout )
273 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800274 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800275 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400276 return main.TRUE
277 else:
kelvin8ec71442015-01-15 16:57:00 -0800278 # If failed, send ctrl+c to process and try again
279 main.log.info( "Starting CLI failed. Retrying..." )
280 self.handle.send( "\x03" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800281 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800282 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
283 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400284 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800285 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800286 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800287 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800288 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800289 "config:property-set -p org.apache.karaf.shell\
290 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800291 karafTimeout )
292 self.handle.expect( "\$" )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 self.handle.sendline( "onos -w " + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400295 return main.TRUE
296 else:
kelvin8ec71442015-01-15 16:57:00 -0800297 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400299 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400300
Jon Halld4d4b372015-01-28 16:02:41 -0800301 except TypeError:
302 main.log.exception( self.name + ": Object not as expected" )
303 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800305 main.log.error( self.name + ": EOF exception found" )
306 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400307 main.cleanup()
308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800310 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400311 main.cleanup()
312 main.exit()
313
suibin zhang116647a2016-05-06 16:30:09 -0700314 def startCellCli( self, karafTimeout="",
315 commandlineTimeout=10, onosStartTimeout=60 ):
316 """
317 Start CLI on onos ecll handle.
318
319 karafTimeout is an optional argument. karafTimeout value passed
320 by user would be used to set the current karaf shell idle timeout.
321 Note that when ever this property is modified the shell will exit and
322 the subsequent login would reflect new idle timeout.
323 Below is an example to start a session with 60 seconds idle timeout
324 ( input value is in milliseconds ):
325
326 tValue = "60000"
327
328 Note: karafTimeout is left as str so that this could be read
329 and passed to startOnosCli from PARAMS file as str.
330 """
331
332 try:
333 self.handle.sendline( "" )
334 x = self.handle.expect( [
335 "\$", "onos>" ], commandlineTimeout)
336
337 if x == 1:
338 main.log.info( "ONOS cli is already running" )
339 return main.TRUE
340
341 # Wait for onos start ( -w ) and enter onos cli
342 self.handle.sendline( "/opt/onos/bin/onos" )
343 i = self.handle.expect( [
344 "onos>",
345 pexpect.TIMEOUT ], onosStartTimeout )
346
347 if i == 0:
348 main.log.info( self.name + " CLI Started successfully" )
349 if karafTimeout:
350 self.handle.sendline(
351 "config:property-set -p org.apache.karaf.shell\
352 sshIdleTimeout " +
353 karafTimeout )
354 self.handle.expect( "\$" )
355 self.handle.sendline( "/opt/onos/bin/onos" )
356 self.handle.expect( "onos>" )
357 return main.TRUE
358 else:
359 # If failed, send ctrl+c to process and try again
360 main.log.info( "Starting CLI failed. Retrying..." )
361 self.handle.send( "\x03" )
362 self.handle.sendline( "/opt/onos/bin/onos" )
363 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
364 timeout=30 )
365 if i == 0:
366 main.log.info( self.name + " CLI Started " +
367 "successfully after retry attempt" )
368 if karafTimeout:
369 self.handle.sendline(
370 "config:property-set -p org.apache.karaf.shell\
371 sshIdleTimeout " +
372 karafTimeout )
373 self.handle.expect( "\$" )
374 self.handle.sendline( "/opt/onos/bin/onos" )
375 self.handle.expect( "onos>" )
376 return main.TRUE
377 else:
378 main.log.error( "Connection to CLI " +
379 self.name + " timeout" )
380 return main.FALSE
381
382 except TypeError:
383 main.log.exception( self.name + ": Object not as expected" )
384 return None
385 except pexpect.EOF:
386 main.log.error( self.name + ": EOF exception found" )
387 main.log.error( self.name + ": " + self.handle.before )
388 main.cleanup()
389 main.exit()
390 except Exception:
391 main.log.exception( self.name + ": Uncaught exception!" )
392 main.cleanup()
393 main.exit()
394
YPZhangebf9eb52016-05-12 15:20:24 -0700395 def log( self, cmdStr, level="",noExit=False):
kelvin-onlab9f541032015-02-04 16:19:53 -0800396 """
397 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800398 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800399 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700400 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800401 Available level: DEBUG, TRACE, INFO, WARN, ERROR
402 Level defaults to INFO
kelvin-onlab9f541032015-02-04 16:19:53 -0800403 """
404 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800405 lvlStr = ""
406 if level:
407 lvlStr = "--level=" + level
408
kelvin-onlab338f5512015-02-06 10:53:16 -0800409 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700410 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800411 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800412
kelvin-onlab9f541032015-02-04 16:19:53 -0800413 response = self.handle.before
414 if re.search( "Error", response ):
415 return main.FALSE
416 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700417 except pexpect.TIMEOUT:
418 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700419 if noExit:
420 main.cleanup()
421 return None
422 else:
423 main.cleanup()
424 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 except pexpect.EOF:
426 main.log.error( self.name + ": EOF exception found" )
427 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700428 if noExit:
429 main.cleanup()
430 return None
431 else:
432 main.cleanup()
433 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800434 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800435 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700436 if noExit:
437 main.cleanup()
438 return None
439 else:
440 main.cleanup()
441 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400442
YPZhangebf9eb52016-05-12 15:20:24 -0700443 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800444 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800445 Send a completely user specified string to
446 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400447 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800448
YPZhangebf9eb52016-05-12 15:20:24 -0700449 if noExit is True, TestON will not exit, but clean up
450
andrewonlaba18f6bf2014-10-13 19:31:54 -0400451 Warning: There are no sanity checking to commands
452 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800453
kelvin8ec71442015-01-15 16:57:00 -0800454 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400455 try:
Jon Halla495f562016-05-16 18:03:26 -0700456 # Try to reconnect if disconnected from cli
457 self.handle.sendline( "" )
458 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
459 if i == 1:
460 main.log.error( self.name + ": onos cli session closed. ")
461 if self.onosIp:
462 main.log.warn( "Trying to reconnect " + self.onosIp )
463 reconnectResult = self.startOnosCli( self.onosIp )
464 if reconnectResult:
465 main.log.info( self.name + ": onos cli session reconnected." )
466 else:
467 main.log.error( self.name + ": reconnection failed." )
468 main.cleanup()
469 main.exit()
470 else:
471 main.cleanup()
472 main.exit()
473 if i == 2:
474 self.handle.sendline( "" )
475 self.handle.expect( "onos>" )
476
Jon Hall14a03b52016-05-11 12:07:30 -0700477 if debug:
478 # NOTE: This adds and average of .4 seconds per call
479 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700480 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800481 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800482 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800483 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800484 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800485 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
486 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700487 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700488 main.log.debug( self.name + ": Raw output" )
489 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700490
491 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800493 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700494 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700495 main.log.debug( self.name + ": ansiEscape output" )
496 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700497
kelvin-onlabfb521662015-02-27 09:52:40 -0800498 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800499 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700500 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700501 main.log.debug( self.name + ": Removed extra returns " +
502 "from output" )
503 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700504
505 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800506 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700507 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700508 main.log.debug( self.name + ": parsed and stripped output" )
509 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700510
Jon Hall63604932015-02-26 17:09:50 -0800511 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700512 output = response.split( cmdStr.strip(), 1 )
513 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700514 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800517 output = output[1].strip()
518 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800519 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800520 return output
GlennRCed771242016-01-13 17:02:47 -0800521 except pexpect.TIMEOUT:
522 main.log.error( self.name + ":ONOS timeout" )
523 if debug:
524 main.log.debug( self.handle.before )
525 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700526 except IndexError:
527 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700528 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700529 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800530 except TypeError:
531 main.log.exception( self.name + ": Object not as expected" )
532 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800534 main.log.error( self.name + ": EOF exception found" )
535 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700536 if noExit:
537 main.cleanup()
538 return None
539 else:
540 main.cleanup()
541 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800542 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800543 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700544 if noExit:
545 main.cleanup()
546 return None
547 else:
548 main.cleanup()
549 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400550
kelvin8ec71442015-01-15 16:57:00 -0800551 # IMPORTANT NOTE:
552 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800553 # the cli command changing 'a:b' with 'aB'.
554 # Ex ) onos:topology > onosTopology
555 # onos:links > onosLinks
556 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800557
kelvin-onlabd3b64892015-01-20 13:26:24 -0800558 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800559 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400560 Adds a new cluster node by ID and address information.
561 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 * nodeId
563 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400564 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800565 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800566 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400567 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 cmdStr = "add-node " + str( nodeId ) + " " +\
569 str( ONOSIp ) + " " + str( tcpPort )
570 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700571 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800572 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800573 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800574 main.log.error( "Error in adding node" )
575 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800576 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400577 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800578 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800580 except AssertionError:
581 main.log.exception( "" )
582 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800583 except TypeError:
584 main.log.exception( self.name + ": Object not as expected" )
585 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800587 main.log.error( self.name + ": EOF exception found" )
588 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400589 main.cleanup()
590 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800591 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800592 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400593 main.cleanup()
594 main.exit()
595
kelvin-onlabd3b64892015-01-20 13:26:24 -0800596 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800597 """
andrewonlab86dc3082014-10-13 18:18:38 -0400598 Removes a cluster by ID
599 Issues command: 'remove-node [<node-id>]'
600 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800602 """
andrewonlab86dc3082014-10-13 18:18:38 -0400603 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400604
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700606 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700607 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800608 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700609 if re.search( "Error", handle ):
610 main.log.error( "Error in removing node" )
611 main.log.error( handle )
612 return main.FALSE
613 else:
614 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800615 except AssertionError:
616 main.log.exception( "" )
617 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800618 except TypeError:
619 main.log.exception( self.name + ": Object not as expected" )
620 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400621 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800622 main.log.error( self.name + ": EOF exception found" )
623 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400624 main.cleanup()
625 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800626 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800627 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400628 main.cleanup()
629 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400630
Jon Hall61282e32015-03-19 11:34:11 -0700631 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800632 """
andrewonlab7c211572014-10-15 16:45:20 -0400633 List the nodes currently visible
634 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700635 Optional argument:
636 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800637 """
andrewonlab7c211572014-10-15 16:45:20 -0400638 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700639 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700640 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700641 cmdStr += " -j"
642 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700643 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800644 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700645 return output
Jon Hallc6793552016-01-19 14:18:37 -0800646 except AssertionError:
647 main.log.exception( "" )
648 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800649 except TypeError:
650 main.log.exception( self.name + ": Object not as expected" )
651 return None
andrewonlab7c211572014-10-15 16:45:20 -0400652 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800653 main.log.error( self.name + ": EOF exception found" )
654 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400655 main.cleanup()
656 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800657 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800658 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400659 main.cleanup()
660 main.exit()
661
kelvin8ec71442015-01-15 16:57:00 -0800662 def topology( self ):
663 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700664 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700665 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700666 Return:
667 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800668 """
andrewonlab95ce8322014-10-13 14:12:04 -0400669 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700670 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800671 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800672 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700673 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400674 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800675 except AssertionError:
676 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800677 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400684 main.cleanup()
685 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800686 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800687 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400688 main.cleanup()
689 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800690
jenkins7ead5a82015-03-13 10:28:21 -0700691 def deviceRemove( self, deviceId ):
692 """
693 Removes particular device from storage
694
695 TODO: refactor this function
696 """
697 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700698 cmdStr = "device-remove " + str( deviceId )
699 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800700 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700701 if re.search( "Error", handle ):
702 main.log.error( "Error in removing device" )
703 main.log.error( handle )
704 return main.FALSE
705 else:
706 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800707 except AssertionError:
708 main.log.exception( "" )
709 return None
jenkins7ead5a82015-03-13 10:28:21 -0700710 except TypeError:
711 main.log.exception( self.name + ": Object not as expected" )
712 return None
713 except pexpect.EOF:
714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
716 main.cleanup()
717 main.exit()
718 except Exception:
719 main.log.exception( self.name + ": Uncaught exception!" )
720 main.cleanup()
721 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700722
kelvin-onlabd3b64892015-01-20 13:26:24 -0800723 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800724 """
Jon Hall7b02d952014-10-17 20:14:54 -0400725 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400726 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800728 """
andrewonlab86dc3082014-10-13 18:18:38 -0400729 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 cmdStr += " -j"
733 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800736 except AssertionError:
737 main.log.exception( "" )
738 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800739 except TypeError:
740 main.log.exception( self.name + ": Object not as expected" )
741 return None
andrewonlab7c211572014-10-15 16:45:20 -0400742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800743 main.log.error( self.name + ": EOF exception found" )
744 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400745 main.cleanup()
746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800748 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400749 main.cleanup()
750 main.exit()
751
kelvin-onlabd3b64892015-01-20 13:26:24 -0800752 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800753 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800754 This balances the devices across all controllers
755 by issuing command: 'onos> onos:balance-masters'
756 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800757 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800758 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800759 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700760 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800761 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700762 if re.search( "Error", handle ):
763 main.log.error( "Error in balancing masters" )
764 main.log.error( handle )
765 return main.FALSE
766 else:
767 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800768 except AssertionError:
769 main.log.exception( "" )
770 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800771 except TypeError:
772 main.log.exception( self.name + ": Object not as expected" )
773 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800774 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800775 main.log.error( self.name + ": EOF exception found" )
776 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800777 main.cleanup()
778 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800779 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800780 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800781 main.cleanup()
782 main.exit()
783
Jon Hallc6793552016-01-19 14:18:37 -0800784 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700785 """
786 Returns the output of the masters command.
787 Optional argument:
788 * jsonFormat - boolean indicating if you want output in json
789 """
790 try:
791 cmdStr = "onos:masters"
792 if jsonFormat:
793 cmdStr += " -j"
794 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700795 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800796 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700797 return output
Jon Hallc6793552016-01-19 14:18:37 -0800798 except AssertionError:
799 main.log.exception( "" )
800 return None
acsmars24950022015-07-30 18:00:43 -0700801 except TypeError:
802 main.log.exception( self.name + ": Object not as expected" )
803 return None
804 except pexpect.EOF:
805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
807 main.cleanup()
808 main.exit()
809 except Exception:
810 main.log.exception( self.name + ": Uncaught exception!" )
811 main.cleanup()
812 main.exit()
813
Jon Hallc6793552016-01-19 14:18:37 -0800814 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700815 """
816 Uses the master command to check that the devices' leadership
817 is evenly divided
818
819 Dependencies: checkMasters() and summary()
820
Jon Hall6509dbf2016-06-21 17:01:17 -0700821 Returns main.TRUE if the devices are balanced
822 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700823 Exits on Exception
824 Returns None on TypeError
825 """
826 try:
Jon Hallc6793552016-01-19 14:18:37 -0800827 summaryOutput = self.summary()
828 totalDevices = json.loads( summaryOutput )[ "devices" ]
829 except ( TypeError, ValueError ):
830 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
831 return None
832 try:
acsmars24950022015-07-30 18:00:43 -0700833 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800834 mastersOutput = self.checkMasters()
835 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700836 first = masters[ 0 ][ "size" ]
837 for master in masters:
838 totalOwnedDevices += master[ "size" ]
839 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
840 main.log.error( "Mastership not balanced" )
841 main.log.info( "\n" + self.checkMasters( False ) )
842 return main.FALSE
843 main.log.info( "Mastership balanced between " \
844 + str( len(masters) ) + " masters" )
845 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800846 except ( TypeError, ValueError ):
847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700848 return None
849 except pexpect.EOF:
850 main.log.error( self.name + ": EOF exception found" )
851 main.log.error( self.name + ": " + self.handle.before )
852 main.cleanup()
853 main.exit()
854 except Exception:
855 main.log.exception( self.name + ": Uncaught exception!" )
856 main.cleanup()
857 main.exit()
858
YPZhangfebf7302016-05-24 16:45:56 -0700859 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Halle8217482014-10-17 13:49:14 -0400861 Lists all core links
862 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800864 """
Jon Halle8217482014-10-17 13:49:14 -0400865 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700869 handle = self.sendline( cmdStr, timeout=timeout )
Jon Hallc6793552016-01-19 14:18:37 -0800870 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700871 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800872 except AssertionError:
873 main.log.exception( "" )
874 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800875 except TypeError:
876 main.log.exception( self.name + ": Object not as expected" )
877 return None
Jon Halle8217482014-10-17 13:49:14 -0400878 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800879 main.log.error( self.name + ": EOF exception found" )
880 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400881 main.cleanup()
882 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400885 main.cleanup()
886 main.exit()
887
kelvin-onlabd3b64892015-01-20 13:26:24 -0800888 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800889 """
Jon Halle8217482014-10-17 13:49:14 -0400890 Lists all ports
891 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800892 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800893 """
Jon Halle8217482014-10-17 13:49:14 -0400894 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700897 cmdStr += " -j"
898 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800899 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800901 except AssertionError:
902 main.log.exception( "" )
903 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800904 except TypeError:
905 main.log.exception( self.name + ": Object not as expected" )
906 return None
Jon Halle8217482014-10-17 13:49:14 -0400907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800908 main.log.error( self.name + ": EOF exception found" )
909 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400910 main.cleanup()
911 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800912 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800913 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400914 main.cleanup()
915 main.exit()
916
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800918 """
Jon Hall983a1702014-10-28 18:44:22 -0400919 Lists all devices and the controllers with roles assigned to them
920 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800921 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800922 """
andrewonlab7c211572014-10-15 16:45:20 -0400923 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700924 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700926 cmdStr += " -j"
927 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -0800928 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700929 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800930 except AssertionError:
931 main.log.exception( "" )
932 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800933 except TypeError:
934 main.log.exception( self.name + ": Object not as expected" )
935 return None
Jon Hall983a1702014-10-28 18:44:22 -0400936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800937 main.log.error( self.name + ": EOF exception found" )
938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400939 main.cleanup()
940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400943 main.cleanup()
944 main.exit()
945
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800947 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800948 Given the a string containing the json representation of the "roles"
949 cli command and a partial or whole device id, returns a json object
950 containing the roles output for the first device whose id contains
951 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400952
953 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 A dict of the role assignments for the given device or
955 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800956 """
Jon Hall983a1702014-10-28 18:44:22 -0400957 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800958 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400959 return None
960 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800961 rawRoles = self.roles()
962 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800963 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800965 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400967 return device
968 return None
Jon Hallc6793552016-01-19 14:18:37 -0800969 except ( TypeError, ValueError ):
970 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800971 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400972 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800973 main.log.error( self.name + ": EOF exception found" )
974 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400975 main.cleanup()
976 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800977 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800978 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400979 main.cleanup()
980 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800981
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800983 """
Jon Hall94fd0472014-12-08 11:52:42 -0800984 Iterates through each device and checks if there is a master assigned
985 Returns: main.TRUE if each device has a master
986 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800987 """
Jon Hall94fd0472014-12-08 11:52:42 -0800988 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 rawRoles = self.roles()
990 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800991 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800992 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800993 # print device
994 if device[ 'master' ] == "none":
995 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800996 return main.FALSE
997 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800998 except ( TypeError, ValueError ):
999 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001000 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001001 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001002 main.log.error( self.name + ": EOF exception found" )
1003 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001004 main.cleanup()
1005 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001006 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001007 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001008 main.cleanup()
1009 main.exit()
1010
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001012 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001013 Returns string of paths, and the cost.
1014 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1018 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001019 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001020 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( "Error in getting paths" )
1022 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001023 else:
kelvin8ec71442015-01-15 16:57:00 -08001024 path = handle.split( ";" )[ 0 ]
1025 cost = handle.split( ";" )[ 1 ]
1026 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001027 except AssertionError:
1028 main.log.exception( "" )
1029 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001030 except TypeError:
1031 main.log.exception( self.name + ": Object not as expected" )
1032 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001033 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001034 main.log.error( self.name + ": EOF exception found" )
1035 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001036 main.cleanup()
1037 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001038 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001039 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001040 main.cleanup()
1041 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001042
kelvin-onlabd3b64892015-01-20 13:26:24 -08001043 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001044 """
Jon Hallffb386d2014-11-21 13:43:38 -08001045 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001046 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001048 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001049 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001050 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr += " -j"
1053 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001054 if handle:
1055 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001056 # TODO: Maybe make this less hardcoded
1057 # ConsistentMap Exceptions
1058 assert "org.onosproject.store.service" not in handle
1059 # Node not leader
1060 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001061 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001062 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001063 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001064 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001065 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001066 except TypeError:
1067 main.log.exception( self.name + ": Object not as expected" )
1068 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001070 main.log.error( self.name + ": EOF exception found" )
1071 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001072 main.cleanup()
1073 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001076 main.cleanup()
1077 main.exit()
1078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001109 main.cleanup()
1110 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001112 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001113 main.cleanup()
1114 main.exit()
1115
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001117 """
1118 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001120
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001122 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001123 IMPORTANT:
1124 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001125 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001126 Furthermore, it assumes that value of VLAN is '-1'
1127 Description:
kelvin8ec71442015-01-15 16:57:00 -08001128 Converts mininet hosts ( h1, h2, h3... ) into
1129 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1130 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001135 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 hostHex = hex( int( host ) ).zfill( 12 )
1137 hostHex = str( hostHex ).replace( 'x', '0' )
1138 i = iter( str( hostHex ) )
1139 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1140 hostHex = hostHex + "/-1"
1141 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144
Jon Halld4d4b372015-01-28 16:02:41 -08001145 except TypeError:
1146 main.log.exception( self.name + ": Object not as expected" )
1147 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001149 main.log.error( self.name + ": EOF exception found" )
1150 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001151 main.cleanup()
1152 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001154 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001155 main.cleanup()
1156 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001157
Jeremy Songsterff553672016-05-12 17:06:23 -07001158 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001159 """
andrewonlabe6745342014-10-17 14:29:13 -04001160 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 * hostIdOne: ONOS host id for host1
1162 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001163 Optional:
1164 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001165 * setVlan: specify a VLAN id treatment
andrewonlabe6745342014-10-17 14:29:13 -04001166 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001167 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001168 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001169 Returns:
1170 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001171 """
andrewonlabe6745342014-10-17 14:29:13 -04001172 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001173 cmdStr = "add-host-intent "
1174 if vlanId:
1175 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001176 if setVlan:
1177 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001180 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001181 if re.search( "Error", handle ):
1182 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001183 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001184 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001185 else:
1186 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1188 match = re.search('id=0x([\da-f]+),', handle)
1189 if match:
1190 return match.group()[3:-1]
1191 else:
1192 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001193 main.log.debug( "Response from ONOS was: " +
1194 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001195 return None
Jon Hallc6793552016-01-19 14:18:37 -08001196 except AssertionError:
1197 main.log.exception( "" )
1198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001199 except TypeError:
1200 main.log.exception( self.name + ": Object not as expected" )
1201 return None
andrewonlabe6745342014-10-17 14:29:13 -04001202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001203 main.log.error( self.name + ": EOF exception found" )
1204 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001205 main.cleanup()
1206 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001209 main.cleanup()
1210 main.exit()
1211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001213 """
andrewonlab7b31d232014-10-24 13:31:47 -04001214 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 * ingressDevice: device id of ingress device
1216 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001217 Optional:
1218 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001219 Description:
1220 Adds an optical intent by specifying an ingress and egress device
1221 Returns:
1222 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 """
andrewonlab7b31d232014-10-24 13:31:47 -04001224 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1226 " " + str( egressDevice )
1227 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001228 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001229 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "Error in adding Optical intent" )
1232 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001233 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 main.log.info( "Optical intent installed between " +
1235 str( ingressDevice ) + " and " +
1236 str( egressDevice ) )
1237 match = re.search('id=0x([\da-f]+),', handle)
1238 if match:
1239 return match.group()[3:-1]
1240 else:
1241 main.log.error( "Error, intent ID not found" )
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except AssertionError:
1244 main.log.exception( "" )
1245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001246 except TypeError:
1247 main.log.exception( self.name + ": Object not as expected" )
1248 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001252 main.cleanup()
1253 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001255 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001256 main.cleanup()
1257 main.exit()
1258
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001260 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 ingressDevice,
1262 egressDevice,
1263 portIngress="",
1264 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001265 ethType="",
1266 ethSrc="",
1267 ethDst="",
1268 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 ipProto="",
1271 ipSrc="",
1272 ipDst="",
1273 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001274 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 vlanId="",
1276 setVlan="" ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * ingressDevice: device id of ingress device
1280 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001293 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001294 * setVlan: specify a VLAN id treatment
andrewonlab4dbb4d82014-10-17 18:22:31 -04001295 Description:
kelvin8ec71442015-01-15 16:57:00 -08001296 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001297 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 Returns:
1299 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001300
Jon Halle3f39ff2015-01-13 11:50:53 -08001301 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001302 options developers provide for point-to-point
1303 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001304 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001305 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001306 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001307
Jeremy Songsterff553672016-05-12 17:06:23 -07001308 if ethType:
1309 cmd += " --ethType " + str( ethType )
1310 if ethSrc:
1311 cmd += " --ethSrc " + str( ethSrc )
1312 if ethDst:
1313 cmd += " --ethDst " + str( ethDst )
1314 if bandwidth:
1315 cmd += " --bandwidth " + str( bandwidth )
1316 if lambdaAlloc:
1317 cmd += " --lambda "
1318 if ipProto:
1319 cmd += " --ipProto " + str( ipProto )
1320 if ipSrc:
1321 cmd += " --ipSrc " + str( ipSrc )
1322 if ipDst:
1323 cmd += " --ipDst " + str( ipDst )
1324 if tcpSrc:
1325 cmd += " --tcpSrc " + str( tcpSrc )
1326 if tcpDst:
1327 cmd += " --tcpDst " + str( tcpDst )
1328 if vlanId:
1329 cmd += " -v " + str( vlanId )
1330 if setVlan:
1331 cmd += " --setVlan " + str( setVlan )
andrewonlab289e4b72014-10-21 21:24:18 -04001332
kelvin8ec71442015-01-15 16:57:00 -08001333 # Check whether the user appended the port
1334 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001335 if "/" in ingressDevice:
1336 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001337 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001338 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001339 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001340 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001341 # Would it make sense to throw an exception and exit
1342 # the test?
1343 return None
andrewonlab36af3822014-11-18 17:48:18 -05001344
kelvin8ec71442015-01-15 16:57:00 -08001345 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 str( ingressDevice ) + "/" +\
1347 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001348
kelvin-onlabd3b64892015-01-20 13:26:24 -08001349 if "/" in egressDevice:
1350 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001351 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001353 main.log.error( "You must specify the egress port" )
1354 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001355
kelvin8ec71442015-01-15 16:57:00 -08001356 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 str( egressDevice ) + "/" +\
1358 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001359
kelvin-onlab898a6c62015-01-16 14:13:53 -08001360 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001361 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001362 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001363 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001364 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001365 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001366 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001367 # TODO: print out all the options in this message?
1368 main.log.info( "Point-to-point intent installed between " +
1369 str( ingressDevice ) + " and " +
1370 str( egressDevice ) )
1371 match = re.search('id=0x([\da-f]+),', handle)
1372 if match:
1373 return match.group()[3:-1]
1374 else:
1375 main.log.error( "Error, intent ID not found" )
1376 return None
Jon Hallc6793552016-01-19 14:18:37 -08001377 except AssertionError:
1378 main.log.exception( "" )
1379 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001380 except TypeError:
1381 main.log.exception( self.name + ": Object not as expected" )
1382 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001383 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001384 main.log.error( self.name + ": EOF exception found" )
1385 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001386 main.cleanup()
1387 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001388 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001389 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001390 main.cleanup()
1391 main.exit()
1392
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001394 self,
shahshreyac2f97072015-03-19 17:04:29 -07001395 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001396 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001397 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 ethType="",
1400 ethSrc="",
1401 ethDst="",
1402 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 ipProto="",
1405 ipSrc="",
1406 ipDst="",
1407 tcpSrc="",
1408 tcpDst="",
1409 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001410 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001411 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001412 setVlan="",
1413 partial=False ):
kelvin8ec71442015-01-15 16:57:00 -08001414 """
shahshreyad0c80432014-12-04 16:56:05 -08001415 Note:
shahshreya70622b12015-03-19 17:19:00 -07001416 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001417 is same. That is, all ingress devices include port numbers
1418 with a "/" or all ingress devices could specify device
1419 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001420 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001421 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001422 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001424 Optional:
1425 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001426 * ethSrc: specify ethSrc ( i.e. src mac addr )
1427 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001428 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001430 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001431 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001432 * ipSrc: specify ip source address
1433 * ipDst: specify ip destination address
1434 * tcpSrc: specify tcp source port
1435 * tcpDst: specify tcp destination port
1436 * setEthSrc: action to Rewrite Source MAC Address
1437 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001438 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001439 * setVlan: specify VLAN Id treatment
shahshreyad0c80432014-12-04 16:56:05 -08001440 Description:
kelvin8ec71442015-01-15 16:57:00 -08001441 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001442 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 Returns:
1444 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001445
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001447 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001448 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001449 """
shahshreyad0c80432014-12-04 16:56:05 -08001450 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001451 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001452
Jeremy Songsterff553672016-05-12 17:06:23 -07001453 if ethType:
1454 cmd += " --ethType " + str( ethType )
1455 if ethSrc:
1456 cmd += " --ethSrc " + str( ethSrc )
1457 if ethDst:
1458 cmd += " --ethDst " + str( ethDst )
1459 if bandwidth:
1460 cmd += " --bandwidth " + str( bandwidth )
1461 if lambdaAlloc:
1462 cmd += " --lambda "
1463 if ipProto:
1464 cmd += " --ipProto " + str( ipProto )
1465 if ipSrc:
1466 cmd += " --ipSrc " + str( ipSrc )
1467 if ipDst:
1468 cmd += " --ipDst " + str( ipDst )
1469 if tcpSrc:
1470 cmd += " --tcpSrc " + str( tcpSrc )
1471 if tcpDst:
1472 cmd += " --tcpDst " + str( tcpDst )
1473 if setEthSrc:
1474 cmd += " --setEthSrc " + str( setEthSrc )
1475 if setEthDst:
1476 cmd += " --setEthDst " + str( setEthDst )
1477 if vlanId:
1478 cmd += " -v " + str( vlanId )
1479 if setVlan:
1480 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001481 if partial:
1482 cmd += " --partial"
shahshreyad0c80432014-12-04 16:56:05 -08001483
kelvin8ec71442015-01-15 16:57:00 -08001484 # Check whether the user appended the port
1485 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001486
1487 if portIngressList is None:
1488 for ingressDevice in ingressDeviceList:
1489 if "/" in ingressDevice:
1490 cmd += " " + str( ingressDevice )
1491 else:
1492 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001493 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001494 # TODO: perhaps more meaningful return
1495 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001496 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001497 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001498 for ingressDevice, portIngress in zip( ingressDeviceList,
1499 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001500 cmd += " " + \
1501 str( ingressDevice ) + "/" +\
1502 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001503 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001504 main.log.error( "Device list and port list does not " +
1505 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001506 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 if "/" in egressDevice:
1508 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001509 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001511 main.log.error( "You must specify " +
1512 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001513 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001514
kelvin8ec71442015-01-15 16:57:00 -08001515 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 str( egressDevice ) + "/" +\
1517 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001518 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001519 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001520 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001521 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 main.log.error( "Error in adding multipoint-to-singlepoint " +
1523 "intent" )
1524 return None
shahshreyad0c80432014-12-04 16:56:05 -08001525 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001526 match = re.search('id=0x([\da-f]+),', handle)
1527 if match:
1528 return match.group()[3:-1]
1529 else:
1530 main.log.error( "Error, intent ID not found" )
1531 return None
Jon Hallc6793552016-01-19 14:18:37 -08001532 except AssertionError:
1533 main.log.exception( "" )
1534 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001535 except TypeError:
1536 main.log.exception( self.name + ": Object not as expected" )
1537 return None
1538 except pexpect.EOF:
1539 main.log.error( self.name + ": EOF exception found" )
1540 main.log.error( self.name + ": " + self.handle.before )
1541 main.cleanup()
1542 main.exit()
1543 except Exception:
1544 main.log.exception( self.name + ": Uncaught exception!" )
1545 main.cleanup()
1546 main.exit()
1547
1548 def addSinglepointToMultipointIntent(
1549 self,
1550 ingressDevice,
1551 egressDeviceList,
1552 portIngress="",
1553 portEgressList=None,
1554 ethType="",
1555 ethSrc="",
1556 ethDst="",
1557 bandwidth="",
1558 lambdaAlloc=False,
1559 ipProto="",
1560 ipSrc="",
1561 ipDst="",
1562 tcpSrc="",
1563 tcpDst="",
1564 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001565 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001566 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001567 setVlan="",
1568 partial=False ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001569 """
1570 Note:
1571 This function assumes the format of all egress devices
1572 is same. That is, all egress devices include port numbers
1573 with a "/" or all egress devices could specify device
1574 ids and port numbers seperately.
1575 Required:
1576 * EgressDeviceList: List of device ids of egress device
1577 ( Atleast 2 eress devices required in the list )
1578 * ingressDevice: device id of ingress device
1579 Optional:
1580 * ethType: specify ethType
1581 * ethSrc: specify ethSrc ( i.e. src mac addr )
1582 * ethDst: specify ethDst ( i.e. dst mac addr )
1583 * bandwidth: specify bandwidth capacity of link
1584 * lambdaAlloc: if True, intent will allocate lambda
1585 for the specified intent
1586 * ipProto: specify ip protocol
1587 * ipSrc: specify ip source address
1588 * ipDst: specify ip destination address
1589 * tcpSrc: specify tcp source port
1590 * tcpDst: specify tcp destination port
1591 * setEthSrc: action to Rewrite Source MAC Address
1592 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001593 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001594 * setVlan: specify VLAN ID treatment
kelvin-onlabb9408212015-04-01 13:34:04 -07001595 Description:
1596 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1597 specifying device id's and optional fields
1598 Returns:
1599 A string of the intent id or None on error
1600
1601 NOTE: This function may change depending on the
1602 options developers provide for singlepoint-to-multipoint
1603 intent via cli
1604 """
1605 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001606 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001607
Jeremy Songsterff553672016-05-12 17:06:23 -07001608 if ethType:
1609 cmd += " --ethType " + str( ethType )
1610 if ethSrc:
1611 cmd += " --ethSrc " + str( ethSrc )
1612 if ethDst:
1613 cmd += " --ethDst " + str( ethDst )
1614 if bandwidth:
1615 cmd += " --bandwidth " + str( bandwidth )
1616 if lambdaAlloc:
1617 cmd += " --lambda "
1618 if ipProto:
1619 cmd += " --ipProto " + str( ipProto )
1620 if ipSrc:
1621 cmd += " --ipSrc " + str( ipSrc )
1622 if ipDst:
1623 cmd += " --ipDst " + str( ipDst )
1624 if tcpSrc:
1625 cmd += " --tcpSrc " + str( tcpSrc )
1626 if tcpDst:
1627 cmd += " --tcpDst " + str( tcpDst )
1628 if setEthSrc:
1629 cmd += " --setEthSrc " + str( setEthSrc )
1630 if setEthDst:
1631 cmd += " --setEthDst " + str( setEthDst )
1632 if vlanId:
1633 cmd += " -v " + str( vlanId )
1634 if setVlan:
1635 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001636 if partial:
1637 cmd += " --partial"
kelvin-onlabb9408212015-04-01 13:34:04 -07001638
1639 # Check whether the user appended the port
1640 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001641
kelvin-onlabb9408212015-04-01 13:34:04 -07001642 if "/" in ingressDevice:
1643 cmd += " " + str( ingressDevice )
1644 else:
1645 if not portIngress:
1646 main.log.error( "You must specify " +
1647 "the Ingress port" )
1648 return main.FALSE
1649
1650 cmd += " " +\
1651 str( ingressDevice ) + "/" +\
1652 str( portIngress )
1653
1654 if portEgressList is None:
1655 for egressDevice in egressDeviceList:
1656 if "/" in egressDevice:
1657 cmd += " " + str( egressDevice )
1658 else:
1659 main.log.error( "You must specify " +
1660 "the egress port" )
1661 # TODO: perhaps more meaningful return
1662 return main.FALSE
1663 else:
1664 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001665 for egressDevice, portEgress in zip( egressDeviceList,
1666 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001667 cmd += " " + \
1668 str( egressDevice ) + "/" +\
1669 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001670 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001671 main.log.error( "Device list and port list does not " +
1672 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001673 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001674 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001675 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001676 # If error, return error message
1677 if re.search( "Error", handle ):
1678 main.log.error( "Error in adding singlepoint-to-multipoint " +
1679 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001680 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001681 else:
1682 match = re.search('id=0x([\da-f]+),', handle)
1683 if match:
1684 return match.group()[3:-1]
1685 else:
1686 main.log.error( "Error, intent ID not found" )
1687 return None
Jon Hallc6793552016-01-19 14:18:37 -08001688 except AssertionError:
1689 main.log.exception( "" )
1690 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001691 except TypeError:
1692 main.log.exception( self.name + ": Object not as expected" )
1693 return None
shahshreyad0c80432014-12-04 16:56:05 -08001694 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001695 main.log.error( self.name + ": EOF exception found" )
1696 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001697 main.cleanup()
1698 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001699 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001700 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001701 main.cleanup()
1702 main.exit()
1703
Hari Krishna9e232602015-04-13 17:29:08 -07001704 def addMplsIntent(
1705 self,
1706 ingressDevice,
1707 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001708 ingressPort="",
1709 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001710 ethType="",
1711 ethSrc="",
1712 ethDst="",
1713 bandwidth="",
1714 lambdaAlloc=False,
1715 ipProto="",
1716 ipSrc="",
1717 ipDst="",
1718 tcpSrc="",
1719 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001720 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001721 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001722 priority=""):
1723 """
1724 Required:
1725 * ingressDevice: device id of ingress device
1726 * egressDevice: device id of egress device
1727 Optional:
1728 * ethType: specify ethType
1729 * ethSrc: specify ethSrc ( i.e. src mac addr )
1730 * ethDst: specify ethDst ( i.e. dst mac addr )
1731 * bandwidth: specify bandwidth capacity of link
1732 * lambdaAlloc: if True, intent will allocate lambda
1733 for the specified intent
1734 * ipProto: specify ip protocol
1735 * ipSrc: specify ip source address
1736 * ipDst: specify ip destination address
1737 * tcpSrc: specify tcp source port
1738 * tcpDst: specify tcp destination port
1739 * ingressLabel: Ingress MPLS label
1740 * egressLabel: Egress MPLS label
1741 Description:
1742 Adds MPLS intent by
1743 specifying device id's and optional fields
1744 Returns:
1745 A string of the intent id or None on error
1746
1747 NOTE: This function may change depending on the
1748 options developers provide for MPLS
1749 intent via cli
1750 """
1751 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001752 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001753
Jeremy Songsterff553672016-05-12 17:06:23 -07001754 if ethType:
1755 cmd += " --ethType " + str( ethType )
1756 if ethSrc:
1757 cmd += " --ethSrc " + str( ethSrc )
1758 if ethDst:
1759 cmd += " --ethDst " + str( ethDst )
1760 if bandwidth:
1761 cmd += " --bandwidth " + str( bandwidth )
1762 if lambdaAlloc:
1763 cmd += " --lambda "
1764 if ipProto:
1765 cmd += " --ipProto " + str( ipProto )
1766 if ipSrc:
1767 cmd += " --ipSrc " + str( ipSrc )
1768 if ipDst:
1769 cmd += " --ipDst " + str( ipDst )
1770 if tcpSrc:
1771 cmd += " --tcpSrc " + str( tcpSrc )
1772 if tcpDst:
1773 cmd += " --tcpDst " + str( tcpDst )
1774 if ingressLabel:
1775 cmd += " --ingressLabel " + str( ingressLabel )
1776 if egressLabel:
1777 cmd += " --egressLabel " + str( egressLabel )
1778 if priority:
1779 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001780
1781 # Check whether the user appended the port
1782 # or provided it as an input
1783 if "/" in ingressDevice:
1784 cmd += " " + str( ingressDevice )
1785 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001786 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001787 main.log.error( "You must specify the ingress port" )
1788 return None
1789
1790 cmd += " " + \
1791 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001792 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001793
1794 if "/" in egressDevice:
1795 cmd += " " + str( egressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the egress port" )
1799 return None
1800
1801 cmd += " " +\
1802 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 handle = self.sendline( cmd )
Jon Hallc6793552016-01-19 14:18:37 -08001806 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001807 # If error, return error message
1808 if re.search( "Error", handle ):
1809 main.log.error( "Error in adding mpls intent" )
1810 return None
1811 else:
1812 # TODO: print out all the options in this message?
1813 main.log.info( "MPLS intent installed between " +
1814 str( ingressDevice ) + " and " +
1815 str( egressDevice ) )
1816 match = re.search('id=0x([\da-f]+),', handle)
1817 if match:
1818 return match.group()[3:-1]
1819 else:
1820 main.log.error( "Error, intent ID not found" )
1821 return None
Jon Hallc6793552016-01-19 14:18:37 -08001822 except AssertionError:
1823 main.log.exception( "" )
1824 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001825 except TypeError:
1826 main.log.exception( self.name + ": Object not as expected" )
1827 return None
1828 except pexpect.EOF:
1829 main.log.error( self.name + ": EOF exception found" )
1830 main.log.error( self.name + ": " + self.handle.before )
1831 main.cleanup()
1832 main.exit()
1833 except Exception:
1834 main.log.exception( self.name + ": Uncaught exception!" )
1835 main.cleanup()
1836 main.exit()
1837
Jon Hallefbd9792015-03-05 16:11:36 -08001838 def removeIntent( self, intentId, app='org.onosproject.cli',
1839 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001840 """
shahshreya1c818fc2015-02-26 13:44:08 -08001841 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001842 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001843 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001844 -p or --purge: Purge the intent from the store after removal
1845
Jon Halle3f39ff2015-01-13 11:50:53 -08001846 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001847 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001848 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001850 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001851 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001852 if purge:
1853 cmdStr += " -p"
1854 if sync:
1855 cmdStr += " -s"
1856
1857 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001858 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001859 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001860 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001861 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001862 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001863 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001864 # TODO: Should this be main.TRUE
1865 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001866 except AssertionError:
1867 main.log.exception( "" )
1868 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001869 except TypeError:
1870 main.log.exception( self.name + ": Object not as expected" )
1871 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001872 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001873 main.log.error( self.name + ": EOF exception found" )
1874 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001875 main.cleanup()
1876 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001879 main.cleanup()
1880 main.exit()
1881
YPZhangfebf7302016-05-24 16:45:56 -07001882 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001883 """
1884 Description:
1885 Remove all the intents
1886 Optional args:-
1887 -s or --sync: Waits for the removal before returning
1888 -p or --purge: Purge the intent from the store after removal
1889 Returns:
1890 Returns main.TRUE if all intents are removed, otherwise returns
1891 main.FALSE; Returns None for exception
1892 """
1893 try:
1894 cmdStr = "remove-intent"
1895 if purge:
1896 cmdStr += " -p"
1897 if sync:
1898 cmdStr += " -s"
1899
1900 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001901 handle = self.sendline( cmdStr, timeout=timeout )
Jeremy42df2e72016-02-23 16:37:46 -08001902 assert "Command not found:" not in handle, handle
1903 if re.search( "Error", handle ):
1904 main.log.error( "Error in removing intent" )
1905 return main.FALSE
1906 else:
1907 return main.TRUE
1908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
1911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
1914 except pexpect.EOF:
1915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
1917 main.cleanup()
1918 main.exit()
1919 except Exception:
1920 main.log.exception( self.name + ": Uncaught exception!" )
1921 main.cleanup()
1922 main.exit()
1923
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001924 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001925 """
1926 Purges all WITHDRAWN Intents
1927 """
1928 try:
1929 cmdStr = "purge-intents"
1930 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001931 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 if re.search( "Error", handle ):
1933 main.log.error( "Error in purging intents" )
1934 return main.FALSE
1935 else:
1936 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001937 except AssertionError:
1938 main.log.exception( "" )
1939 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 except TypeError:
1941 main.log.exception( self.name + ": Object not as expected" )
1942 return None
1943 except pexpect.EOF:
1944 main.log.error( self.name + ": EOF exception found" )
1945 main.log.error( self.name + ": " + self.handle.before )
1946 main.cleanup()
1947 main.exit()
1948 except Exception:
1949 main.log.exception( self.name + ": Uncaught exception!" )
1950 main.cleanup()
1951 main.exit()
1952
kelvin-onlabd3b64892015-01-20 13:26:24 -08001953 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001954 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001955 NOTE: This method should be used after installing application:
1956 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001957 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001958 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001959 Description:
1960 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001961 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001965 cmdStr += " -j"
1966 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001967 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001969 except AssertionError:
1970 main.log.exception( "" )
1971 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001972 except TypeError:
1973 main.log.exception( self.name + ": Object not as expected" )
1974 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001976 main.log.error( self.name + ": EOF exception found" )
1977 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08001978 main.cleanup()
1979 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001981 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 main.cleanup()
1983 main.exit()
1984
pingping-lin54b03372015-08-13 14:43:10 -07001985 def ipv4RouteNumber( self ):
1986 """
1987 NOTE: This method should be used after installing application:
1988 onos-app-sdnip
1989 Description:
1990 Obtain the total IPv4 routes number in the system
1991 """
1992 try:
1993 cmdStr = "routes -s -j"
1994 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08001995 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07001996 jsonResult = json.loads( handle )
1997 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08001998 except AssertionError:
1999 main.log.exception( "" )
2000 return None
2001 except ( TypeError, ValueError ):
2002 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002003 return None
2004 except pexpect.EOF:
2005 main.log.error( self.name + ": EOF exception found" )
2006 main.log.error( self.name + ": " + self.handle.before )
2007 main.cleanup()
2008 main.exit()
2009 except Exception:
2010 main.log.exception( self.name + ": Uncaught exception!" )
2011 main.cleanup()
2012 main.exit()
2013
pingping-lin8244a3b2015-09-16 13:36:56 -07002014 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002015 """
andrewonlabe6745342014-10-17 14:29:13 -04002016 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002017 Obtain intents from the ONOS cli.
2018 Optional:
2019 * jsonFormat: Enable output formatting in json, default to True
2020 * summary: Whether only output the intent summary, defaults to False
2021 * type: Only output a certain type of intent. This options is valid
2022 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002023 """
andrewonlabe6745342014-10-17 14:29:13 -04002024 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002025 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002026 if summary:
2027 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002028 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002029 cmdStr += " -j"
2030 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002031 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002032 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002033 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002034 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002035 else:
Jon Hallff566d52016-01-15 14:45:36 -08002036 intentType = ""
2037 # IF we want the summary of a specific intent type
2038 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002039 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002040 if intentType in jsonResult.keys():
2041 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002042 else:
Jon Hallff566d52016-01-15 14:45:36 -08002043 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002044 return handle
2045 else:
2046 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
2050 except ( TypeError, ValueError ):
2051 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002052 return None
2053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
2056 main.cleanup()
2057 main.exit()
2058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
2060 main.cleanup()
2061 main.exit()
2062
kelvin-onlab54400a92015-02-26 18:05:51 -08002063 def getIntentState(self, intentsId, intentsJson=None):
2064 """
You Wangfdcbfc42016-05-16 12:16:53 -07002065 Description:
2066 Gets intent state. Accepts a single intent ID (string type) or a
2067 list of intent IDs.
2068 Parameters:
2069 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002070 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002071 Returns:
2072 Returns the state (string type) of the ID if a single intent ID is
2073 accepted.
2074 Returns a list of dictionaries if a list of intent IDs is accepted,
2075 and each dictionary maps 'id' to the Intent ID and 'state' to
2076 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002077 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002078 try:
2079 state = "State is Undefined"
2080 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002081 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002082 else:
Jon Hallc6793552016-01-19 14:18:37 -08002083 rawJson = intentsJson
2084 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002085 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002086 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002087 if intentsId == intent[ 'id' ]:
2088 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002089 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002090 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2091 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002092 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002093 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002094 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002095 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002096 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002097 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002098 if intentsId[ i ] == intents[ 'id' ]:
2099 stateDict[ 'state' ] = intents[ 'state' ]
2100 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002101 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002102 break
Jon Hallefbd9792015-03-05 16:11:36 -08002103 if len( intentsId ) != len( dictList ):
2104 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002105 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002106 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002107 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 return None
Jon Hallc6793552016-01-19 14:18:37 -08002109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
2115 main.cleanup()
2116 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002117 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002118 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002119 main.cleanup()
2120 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002121
kelvin-onlabf512e942015-06-08 19:42:59 -07002122 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002123 """
2124 Description:
2125 Check intents state
2126 Required:
2127 intentsId - List of intents ID to be checked
2128 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002129 expectedState - Check the expected state(s) of each intents
2130 state in the list.
2131 *NOTE: You can pass in a list of expected state,
2132 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002133 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002134 Returns main.TRUE only if all intent are the same as expected states
2135 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002136 """
2137 try:
2138 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002139 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002140 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002141 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002142 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002143 "getting intents state" )
2144 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002145
2146 if isinstance( expectedState, types.StringType ):
2147 for intents in intentsDict:
2148 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002149 main.log.debug( self.name + " : Intent ID - " +
2150 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002151 " actual state = " +
2152 intents.get( 'state' )
2153 + " does not equal expected state = "
2154 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002155 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002156
2157 elif isinstance( expectedState, types.ListType ):
2158 for intents in intentsDict:
2159 if not any( state == intents.get( 'state' ) for state in
2160 expectedState ):
2161 main.log.debug( self.name + " : Intent ID - " +
2162 intents.get( 'id' ) +
2163 " actual state = " +
2164 intents.get( 'state' ) +
2165 " does not equal expected states = "
2166 + str( expectedState ) )
2167 returnValue = main.FALSE
2168
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002169 if returnValue == main.TRUE:
2170 main.log.info( self.name + ": All " +
2171 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002172 " intents are in " + str( expectedState ) +
2173 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002174 return returnValue
2175 except TypeError:
2176 main.log.exception( self.name + ": Object not as expected" )
2177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
2181 main.cleanup()
2182 main.exit()
2183 except Exception:
2184 main.log.exception( self.name + ": Uncaught exception!" )
2185 main.cleanup()
2186 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002187
You Wang66518af2016-05-16 15:32:59 -07002188 def compareIntent( self, intentDict ):
2189 """
2190 Description:
2191 Compare the intent ids and states provided in the argument with all intents in ONOS
2192 Return:
2193 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2194 Arguments:
2195 intentDict: a dictionary which maps intent ids to intent states
2196 """
2197 try:
2198 intentsRaw = self.intents()
2199 intentsJson = json.loads( intentsRaw )
2200 intentDictONOS = {}
2201 for intent in intentsJson:
2202 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
2203 if len( intentDict ) != len( intentDictONOS ):
2204 main.log.info( self.name + ": expected intent count does not match that in ONOS, " +
2205 str( len( intentDict ) ) + " expected and " +
2206 str( len( intentDictONOS ) ) + " actual" )
2207 return main.FALSE
2208 returnValue = main.TRUE
2209 for intentID in intentDict.keys():
2210 if not intentID in intentDictONOS.keys():
2211 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2212 returnValue = main.FALSE
2213 elif intentDict[ intentID ] != intentDictONOS[ intentID ]:
2214 main.log.debug( self.name + ": intent ID - " + intentID +
2215 " expected state is " + intentDict[ intentID ] +
2216 " but actual state is " + intentDictONOS[ intentID ] )
2217 returnValue = main.FALSE
2218 if returnValue == main.TRUE:
2219 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2220 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002221 except KeyError:
2222 main.log.exception( self.name + ": KeyError exception found" )
2223 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002224 except ( TypeError, ValueError ):
2225 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002226 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002227 except pexpect.EOF:
2228 main.log.error( self.name + ": EOF exception found" )
2229 main.log.error( self.name + ": " + self.handle.before )
2230 main.cleanup()
2231 main.exit()
2232 except Exception:
2233 main.log.exception( self.name + ": Uncaught exception!" )
2234 main.cleanup()
2235 main.exit()
2236
GlennRCed771242016-01-13 17:02:47 -08002237 def checkIntentSummary( self, timeout=60 ):
2238 """
2239 Description:
2240 Check the number of installed intents.
2241 Optional:
2242 timeout - the timeout for pexcept
2243 Return:
2244 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2245 , otherwise, returns main.FALSE.
2246 """
2247
2248 try:
2249 cmd = "intents -s -j"
2250
2251 # Check response if something wrong
2252 response = self.sendline( cmd, timeout=timeout )
2253 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002254 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002255 response = json.loads( response )
2256
2257 # get total and installed number, see if they are match
2258 allState = response.get( 'all' )
2259 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002260 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002261 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002262 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002263 return main.FALSE
2264
Jon Hallc6793552016-01-19 14:18:37 -08002265 except ( TypeError, ValueError ):
2266 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002267 return None
2268 except pexpect.EOF:
2269 main.log.error( self.name + ": EOF exception found" )
2270 main.log.error( self.name + ": " + self.handle.before )
2271 main.cleanup()
2272 main.exit()
2273 except Exception:
2274 main.log.exception( self.name + ": Uncaught exception!" )
2275 main.cleanup()
2276 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002277 except pexpect.TIMEOUT:
2278 main.log.error( self.name + ": ONOS timeout" )
2279 return None
GlennRCed771242016-01-13 17:02:47 -08002280
YPZhangebf9eb52016-05-12 15:20:24 -07002281 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -08002282 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002283 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002284 * jsonFormat: enable output formatting in json
Shreya Shah0f01c812014-10-26 20:15:28 -04002285 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002286 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002287 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002288 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002289 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002290 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002291 cmdStr += " -j "
2292 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002293 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002294 assert "Command not found:" not in handle, handle
2295 if re.search( "Error:", handle ):
2296 main.log.error( self.name + ": flows() response: " +
2297 str( handle ) )
2298 return handle
2299 except AssertionError:
2300 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002301 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002302 except TypeError:
2303 main.log.exception( self.name + ": Object not as expected" )
2304 return None
Jon Hallc6793552016-01-19 14:18:37 -08002305 except pexpect.TIMEOUT:
2306 main.log.error( self.name + ": ONOS timeout" )
2307 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002308 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002309 main.log.error( self.name + ": EOF exception found" )
2310 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002311 main.cleanup()
2312 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002313 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002314 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002315 main.cleanup()
2316 main.exit()
2317
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002318 def checkFlowCount(self, min=0, timeout=60 ):
2319 count = int(self.getTotalFlowsNum( timeout=timeout ))
2320 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002321
YPZhangebf9eb52016-05-12 15:20:24 -07002322 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002323 """
2324 Description:
GlennRCed771242016-01-13 17:02:47 -08002325 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002326 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2327 if the count of those states is 0, which means all current flows
2328 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002329 Optional:
GlennRCed771242016-01-13 17:02:47 -08002330 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002331 Return:
2332 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002333 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002334 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002335 """
2336 try:
GlennRCed771242016-01-13 17:02:47 -08002337 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2338 checkedStates = []
2339 statesCount = [0, 0, 0, 0]
2340 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002341 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002342 if rawFlows:
2343 # if we didn't get flows or flows function return None, we should return
2344 # main.Flase
2345 checkedStates.append( json.loads( rawFlows ) )
2346 else:
2347 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002348 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002349 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002350 try:
2351 statesCount[i] += int( c.get( "flowCount" ) )
2352 except TypeError:
2353 main.log.exception( "Json object not as expected" )
2354 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002355
GlennRCed771242016-01-13 17:02:47 -08002356 # We want to count PENDING_ADD if isPENDING is true
2357 if isPENDING:
2358 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2359 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002360 else:
GlennRCed771242016-01-13 17:02:47 -08002361 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2362 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002363 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002364 except ( TypeError, ValueError ):
2365 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002366 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002367
YPZhang240842b2016-05-17 12:00:50 -07002368 except AssertionError:
2369 main.log.exception( "" )
2370 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002371 except pexpect.EOF:
2372 main.log.error( self.name + ": EOF exception found" )
2373 main.log.error( self.name + ": " + self.handle.before )
2374 main.cleanup()
2375 main.exit()
2376 except Exception:
2377 main.log.exception( self.name + ": Uncaught exception!" )
2378 main.cleanup()
2379 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002380 except pexpect.TIMEOUT:
2381 main.log.error( self.name + ": ONOS timeout" )
2382 return None
2383
kelvin-onlab4df89f22015-04-13 18:10:23 -07002384
GlennRCed771242016-01-13 17:02:47 -08002385 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002386 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002387 """
andrewonlab87852b02014-11-19 18:44:19 -05002388 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002389 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002390 a specific point-to-point intent definition
2391 Required:
GlennRCed771242016-01-13 17:02:47 -08002392 * ingress: specify source dpid
2393 * egress: specify destination dpid
2394 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002395 Optional:
GlennRCed771242016-01-13 17:02:47 -08002396 * offset: the keyOffset is where the next batch of intents
2397 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002398 * noExit: If set to True, TestON will not exit if any error when issus command
2399 * getResponse: If set to True, function will return ONOS response.
2400
GlennRCed771242016-01-13 17:02:47 -08002401 Returns: If failed to push test intents, it will returen None,
2402 if successful, return true.
2403 Timeout expection will return None,
2404 TypeError will return false
2405 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002406 """
andrewonlab87852b02014-11-19 18:44:19 -05002407 try:
GlennRCed771242016-01-13 17:02:47 -08002408 if background:
2409 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002410 else:
GlennRCed771242016-01-13 17:02:47 -08002411 back = ""
2412 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002413 ingress,
2414 egress,
2415 batchSize,
2416 offset,
2417 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002418 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Hallc6793552016-01-19 14:18:37 -08002419 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002420 main.log.info( response )
2421 if response == None:
2422 return None
2423
YPZhangb34b7e12016-06-14 14:28:19 -07002424 if getResponse:
2425 return response
2426
GlennRCed771242016-01-13 17:02:47 -08002427 # TODO: We should handle if there is failure in installation
2428 return main.TRUE
2429
Jon Hallc6793552016-01-19 14:18:37 -08002430 except AssertionError:
2431 main.log.exception( "" )
2432 return None
GlennRCed771242016-01-13 17:02:47 -08002433 except pexpect.TIMEOUT:
2434 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002435 return None
andrewonlab87852b02014-11-19 18:44:19 -05002436 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002439 main.cleanup()
2440 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002441 except TypeError:
2442 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002443 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002445 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002446 main.cleanup()
2447 main.exit()
2448
YPZhangebf9eb52016-05-12 15:20:24 -07002449 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002450 """
2451 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002452 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002453 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002454 The number of ADDED flows
YPZhangb5d3f832016-01-23 22:54:26 -08002455 """
YPZhange3109a72016-02-02 11:25:37 -08002456
YPZhangb5d3f832016-01-23 22:54:26 -08002457 try:
YPZhange3109a72016-02-02 11:25:37 -08002458 # get total added flows number
YPZhangf6f14a02016-01-28 15:17:31 -08002459 cmd = "flows -s|grep ADDED|wc -l"
YPZhangebf9eb52016-05-12 15:20:24 -07002460 totalFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhange3109a72016-02-02 11:25:37 -08002461
2462 if totalFlows == None:
2463 # if timeout, we will get total number of all flows, and subtract other states
2464 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2465 checkedStates = []
2466 totalFlows = 0
2467 statesCount = [0, 0, 0, 0]
2468
2469 # get total flows from summary
YPZhangebf9eb52016-05-12 15:20:24 -07002470 response = json.loads( self.sendline( "summary -j", timeout=timeout, noExit=noExit ) )
YPZhange3109a72016-02-02 11:25:37 -08002471 totalFlows = int( response.get("flows") )
2472
2473 for s in states:
2474 rawFlows = self.flows( state=s, timeout = timeout )
2475 if rawFlows == None:
2476 # if timeout, return the total flows number from summary command
2477 return totalFlows
2478 checkedStates.append( json.loads( rawFlows ) )
2479
2480 # Calculate ADDED flows number, equal total subtracts others
2481 for i in range( len( states ) ):
2482 for c in checkedStates[i]:
2483 try:
2484 statesCount[i] += int( c.get( "flowCount" ) )
2485 except TypeError:
2486 main.log.exception( "Json object not as expected" )
2487 totalFlows = totalFlows - int( statesCount[i] )
2488 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
2489
2490 return totalFlows
2491
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002492 return int(totalFlows)
YPZhange3109a72016-02-02 11:25:37 -08002493
You Wangd3cb2ce2016-05-16 14:01:24 -07002494 except ( TypeError, ValueError ):
2495 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002496 return None
2497 except pexpect.EOF:
2498 main.log.error( self.name + ": EOF exception found" )
2499 main.log.error( self.name + ": " + self.handle.before )
2500 main.cleanup()
2501 main.exit()
2502 except Exception:
2503 main.log.exception( self.name + ": Uncaught exception!" )
2504 main.cleanup()
2505 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002506 except pexpect.TIMEOUT:
2507 main.log.error( self.name + ": ONOS timeout" )
2508 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002509
YPZhangebf9eb52016-05-12 15:20:24 -07002510 def getTotalIntentsNum( self, timeout=60 ):
YPZhangb5d3f832016-01-23 22:54:26 -08002511 """
2512 Description:
2513 Get the total number of intents, include every states.
2514 Return:
2515 The number of intents
2516 """
2517 try:
2518 cmd = "summary -j"
YPZhangebf9eb52016-05-12 15:20:24 -07002519 response = self.sendline( cmd, timeout=timeout )
YPZhangb5d3f832016-01-23 22:54:26 -08002520 if response == None:
2521 return -1
2522 response = json.loads( response )
2523 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002524 except ( TypeError, ValueError ):
2525 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002526 return None
2527 except pexpect.EOF:
2528 main.log.error( self.name + ": EOF exception found" )
2529 main.log.error( self.name + ": " + self.handle.before )
2530 main.cleanup()
2531 main.exit()
2532 except Exception:
2533 main.log.exception( self.name + ": Uncaught exception!" )
2534 main.cleanup()
2535 main.exit()
2536
kelvin-onlabd3b64892015-01-20 13:26:24 -08002537 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002538 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002539 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002540 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002541 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002542 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002543 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002544 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002545 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002546 cmdStr += " -j"
2547 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002548 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002549 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002550 except AssertionError:
2551 main.log.exception( "" )
2552 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002553 except TypeError:
2554 main.log.exception( self.name + ": Object not as expected" )
2555 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002557 main.log.error( self.name + ": EOF exception found" )
2558 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002559 main.cleanup()
2560 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002561 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002562 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002563 main.cleanup()
2564 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002565
kelvin-onlabd3b64892015-01-20 13:26:24 -08002566 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002567 """
2568 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002569 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002570 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002571 """
andrewonlab867212a2014-10-22 20:13:38 -04002572 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002573 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002574 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002575 cmdStr += " -j"
2576 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002577 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002578 if handle:
2579 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002580 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002581 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002582 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002583 else:
2584 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002585 except AssertionError:
2586 main.log.exception( "" )
2587 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002588 except TypeError:
2589 main.log.exception( self.name + ": Object not as expected" )
2590 return None
andrewonlab867212a2014-10-22 20:13:38 -04002591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002592 main.log.error( self.name + ": EOF exception found" )
2593 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002594 main.cleanup()
2595 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002596 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002597 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002598 main.cleanup()
2599 main.exit()
2600
kelvin8ec71442015-01-15 16:57:00 -08002601 # Wrapper functions ****************
2602 # Wrapper functions use existing driver
2603 # functions and extends their use case.
2604 # For example, we may use the output of
2605 # a normal driver function, and parse it
2606 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002607
kelvin-onlabd3b64892015-01-20 13:26:24 -08002608 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002609 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002610 Description:
2611 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002612 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002613 try:
kelvin8ec71442015-01-15 16:57:00 -08002614 # Obtain output of intents function
kelvin-onlabfb521662015-02-27 09:52:40 -08002615 intentsStr = self.intents(jsonFormat=False)
kelvin-onlabd3b64892015-01-20 13:26:24 -08002616 intentIdList = []
andrewonlab9a50dfe2014-10-17 17:22:31 -04002617
kelvin8ec71442015-01-15 16:57:00 -08002618 # Parse the intents output for ID's
kelvin-onlabd3b64892015-01-20 13:26:24 -08002619 intentsList = [ s.strip() for s in intentsStr.splitlines() ]
2620 for intents in intentsList:
kelvin-onlabfb521662015-02-27 09:52:40 -08002621 match = re.search('id=0x([\da-f]+),', intents)
2622 if match:
2623 tmpId = match.group()[3:-1]
2624 intentIdList.append( tmpId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002625 return intentIdList
andrewonlab9a50dfe2014-10-17 17:22:31 -04002626
Jon Halld4d4b372015-01-28 16:02:41 -08002627 except TypeError:
2628 main.log.exception( self.name + ": Object not as expected" )
2629 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002631 main.log.error( self.name + ": EOF exception found" )
2632 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002633 main.cleanup()
2634 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002635 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002636 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002637 main.cleanup()
2638 main.exit()
2639
Jon Hall30b82fa2015-03-04 17:15:43 -08002640 def FlowAddedCount( self, deviceId ):
2641 """
2642 Determine the number of flow rules for the given device id that are
2643 in the added state
2644 """
2645 try:
2646 cmdStr = "flows any " + str( deviceId ) + " | " +\
2647 "grep 'state=ADDED' | wc -l"
2648 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002649 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002650 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002651 except AssertionError:
2652 main.log.exception( "" )
2653 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002654 except pexpect.EOF:
2655 main.log.error( self.name + ": EOF exception found" )
2656 main.log.error( self.name + ": " + self.handle.before )
2657 main.cleanup()
2658 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002659 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002660 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002661 main.cleanup()
2662 main.exit()
2663
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002665 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002666 Use 'devices' function to obtain list of all devices
2667 and parse the result to obtain a list of all device
2668 id's. Returns this list. Returns empty list if no
2669 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002670 List is ordered sequentially
2671
andrewonlab3e15ead2014-10-15 14:21:34 -04002672 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002673 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002674 the ids. By obtaining the list of device ids on the fly,
2675 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002676 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002677 try:
kelvin8ec71442015-01-15 16:57:00 -08002678 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002679 devicesStr = self.devices( jsonFormat=False )
2680 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002681
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002683 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002684 return idList
kelvin8ec71442015-01-15 16:57:00 -08002685
2686 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002687 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002688 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002689 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002690 # Split list further into arguments before and after string
2691 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 # append to idList
2693 for arg in tempList:
2694 idList.append( arg.split( "id=" )[ 1 ] )
2695 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002696
Jon Halld4d4b372015-01-28 16:02:41 -08002697 except TypeError:
2698 main.log.exception( self.name + ": Object not as expected" )
2699 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002703 main.cleanup()
2704 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002705 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002706 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002707 main.cleanup()
2708 main.exit()
2709
kelvin-onlabd3b64892015-01-20 13:26:24 -08002710 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002711 """
andrewonlab7c211572014-10-15 16:45:20 -04002712 Uses 'nodes' function to obtain list of all nodes
2713 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002714 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002715 Returns:
2716 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002717 """
andrewonlab7c211572014-10-15 16:45:20 -04002718 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002719 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002721 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002722 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002724 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002726 nodesJson = json.loads( nodesStr )
2727 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002728 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002729 except ( TypeError, ValueError ):
2730 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002731 return None
andrewonlab7c211572014-10-15 16:45:20 -04002732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002735 main.cleanup()
2736 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002737 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002738 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002739 main.cleanup()
2740 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002741
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002743 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002744 Return the first device from the devices api whose 'id' contains 'dpid'
2745 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002746 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002747 try:
kelvin8ec71442015-01-15 16:57:00 -08002748 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002749 return None
2750 else:
kelvin8ec71442015-01-15 16:57:00 -08002751 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002752 rawDevices = self.devices()
2753 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002754 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002756 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2757 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002758 return device
2759 return None
Jon Hallc6793552016-01-19 14:18:37 -08002760 except ( TypeError, ValueError ):
2761 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002762 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002766 main.cleanup()
2767 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002768 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002769 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002770 main.cleanup()
2771 main.exit()
2772
You Wang24139872016-05-03 11:48:47 -07002773 def getTopology( self, topologyOutput ):
2774 """
2775 Definition:
2776 Loads a json topology output
2777 Return:
2778 topology = current ONOS topology
2779 """
2780 import json
2781 try:
2782 # either onos:topology or 'topology' will work in CLI
2783 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002784 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002785 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002786 except ( TypeError, ValueError ):
2787 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2788 return None
You Wang24139872016-05-03 11:48:47 -07002789 except pexpect.EOF:
2790 main.log.error( self.name + ": EOF exception found" )
2791 main.log.error( self.name + ": " + self.handle.before )
2792 main.cleanup()
2793 main.exit()
2794 except Exception:
2795 main.log.exception( self.name + ": Uncaught exception!" )
2796 main.cleanup()
2797 main.exit()
2798
Flavio Castro82ee2f62016-06-07 15:04:12 -07002799 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002800 """
Jon Hallefbd9792015-03-05 16:11:36 -08002801 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002802 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002803 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002804
Flavio Castro82ee2f62016-06-07 15:04:12 -07002805 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002806 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002807 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002808 logLevel = level to log to.
2809 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002810
Jon Hallefbd9792015-03-05 16:11:36 -08002811 Returns: main.TRUE if the number of switches and links are correct,
2812 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002813 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002814 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002815 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002816 try:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002817 summary = json.loads( self.summary() )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002818 except ( TypeError, ValueError ):
2819 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2820 return main.ERROR
2821 try:
2822 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002823 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002824 return main.ERROR
2825 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002826 # Is the number of switches is what we expected
2827 devices = topology.get( 'devices', False )
2828 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002829 nodes = summary.get( 'nodes', False )
2830 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002831 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002832 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002833 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002834 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002835 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2836 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002837 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002838 output = output + "The number of links and switches match "\
2839 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002840 result = main.TRUE
2841 else:
You Wang24139872016-05-03 11:48:47 -07002842 output = output + \
2843 "The number of links and switches does not match " + \
2844 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002845 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002846 output = output + "\n ONOS sees %i devices" % int( devices )
2847 output = output + " (%i expected) " % int( numoswitch )
2848 output = output + "and %i links " % int( links )
2849 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002850 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002851 output = output + "and %i controllers " % int( nodes )
2852 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002854 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002856 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002857 else:
You Wang24139872016-05-03 11:48:47 -07002858 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002859 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002860 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002861 main.log.error( self.name + ": EOF exception found" )
2862 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002863 main.cleanup()
2864 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002865 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002866 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002867 main.cleanup()
2868 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002869
kelvin-onlabd3b64892015-01-20 13:26:24 -08002870 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002871 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002872 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002873 deviceId must be the id of a device as seen in the onos devices command
2874 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002875 role must be either master, standby, or none
2876
Jon Halle3f39ff2015-01-13 11:50:53 -08002877 Returns:
2878 main.TRUE or main.FALSE based on argument verification and
2879 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002880 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002881 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002882 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002883 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002884 cmdStr = "device-role " +\
2885 str( deviceId ) + " " +\
2886 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002887 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002889 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002890 if re.search( "Error", handle ):
2891 # end color output to escape any colours
2892 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002893 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002894 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002895 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002896 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002897 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002898 main.log.error( "Invalid 'role' given to device_role(). " +
2899 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002900 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002901 except AssertionError:
2902 main.log.exception( "" )
2903 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002904 except TypeError:
2905 main.log.exception( self.name + ": Object not as expected" )
2906 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002908 main.log.error( self.name + ": EOF exception found" )
2909 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002910 main.cleanup()
2911 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002912 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002913 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002914 main.cleanup()
2915 main.exit()
2916
kelvin-onlabd3b64892015-01-20 13:26:24 -08002917 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002918 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002919 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002920 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002922 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002923 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002924 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002925 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002926 cmdStr += " -j"
2927 handle = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002928 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002929 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002930 except AssertionError:
2931 main.log.exception( "" )
2932 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002933 except TypeError:
2934 main.log.exception( self.name + ": Object not as expected" )
2935 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002936 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002937 main.log.error( self.name + ": EOF exception found" )
2938 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002939 main.cleanup()
2940 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002941 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002942 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002943 main.cleanup()
2944 main.exit()
2945
kelvin-onlabd3b64892015-01-20 13:26:24 -08002946 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002947 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 CLI command to get the current leader for the Election test application
2949 NOTE: Requires installation of the onos-app-election feature
2950 Returns: Node IP of the leader if one exists
2951 None if none exists
2952 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002953 """
Jon Hall94fd0472014-12-08 11:52:42 -08002954 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 cmdStr = "election-test-leader"
2956 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08002957 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08002958 # Leader
2959 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002960 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08002961 nodeSearch = re.search( leaderPattern, response )
2962 if nodeSearch:
2963 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08002964 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002965 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08002966 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08002967 # no leader
2968 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002969 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002970 nullSearch = re.search( nullPattern, response )
2971 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08002972 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002973 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08002974 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08002975 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07002976 main.log.error( "Error in electionTestLeader on " + self.name +
2977 ": " + "unexpected response" )
2978 main.log.error( repr( response ) )
2979 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002980 except AssertionError:
2981 main.log.exception( "" )
2982 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002983 except TypeError:
2984 main.log.exception( self.name + ": Object not as expected" )
2985 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002987 main.log.error( self.name + ": EOF exception found" )
2988 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08002989 main.cleanup()
2990 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002991 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002992 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08002993 main.cleanup()
2994 main.exit()
2995
kelvin-onlabd3b64892015-01-20 13:26:24 -08002996 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002997 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002998 CLI command to run for leadership of the Election test application.
2999 NOTE: Requires installation of the onos-app-election feature
3000 Returns: Main.TRUE on success
3001 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003002 """
Jon Hall94fd0472014-12-08 11:52:42 -08003003 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003004 cmdStr = "election-test-run"
3005 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003006 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003007 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003008 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003010 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003011 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003012 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003013 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003014 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003015 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003016 main.log.error( "Error in electionTestRun on " + self.name +
3017 ": " + "unexpected response" )
3018 main.log.error( repr( response ) )
3019 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003020 except AssertionError:
3021 main.log.exception( "" )
3022 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003023 except TypeError:
3024 main.log.exception( self.name + ": Object not as expected" )
3025 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003027 main.log.error( self.name + ": EOF exception found" )
3028 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003029 main.cleanup()
3030 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003031 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003032 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003033 main.cleanup()
3034 main.exit()
3035
kelvin-onlabd3b64892015-01-20 13:26:24 -08003036 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003037 """
Jon Hall94fd0472014-12-08 11:52:42 -08003038 * CLI command to withdraw the local node from leadership election for
3039 * the Election test application.
3040 #NOTE: Requires installation of the onos-app-election feature
3041 Returns: Main.TRUE on success
3042 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003043 """
Jon Hall94fd0472014-12-08 11:52:42 -08003044 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003045 cmdStr = "election-test-withdraw"
3046 response = self.sendline( cmdStr )
Jon Hallc6793552016-01-19 14:18:37 -08003047 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003048 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003049 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003050 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003051 if re.search( successPattern, response ):
3052 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003053 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003054 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003055 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003056 main.log.error( "Error in electionTestWithdraw on " +
3057 self.name + ": " + "unexpected response" )
3058 main.log.error( repr( response ) )
3059 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003060 except AssertionError:
3061 main.log.exception( "" )
3062 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003063 except TypeError:
3064 main.log.exception( self.name + ": Object not as expected" )
3065 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003067 main.log.error( self.name + ": EOF exception found" )
3068 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003069 main.cleanup()
3070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003072 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003073 main.cleanup()
3074 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003075
kelvin8ec71442015-01-15 16:57:00 -08003076 def getDevicePortsEnabledCount( self, dpid ):
3077 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003078 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003079 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003080 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003081 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003082 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3083 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003084 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003085 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003086 if re.search( "No such device", output ):
3087 main.log.error( "Error in getting ports" )
3088 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003089 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!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003103 main.cleanup()
3104 main.exit()
3105
kelvin8ec71442015-01-15 16:57:00 -08003106 def getDeviceLinksActiveCount( self, dpid ):
3107 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003108 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003110 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003111 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003112 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3113 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003114 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003115 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003117 main.log.error( "Error in getting ports " )
3118 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003119 return output
Jon Hallc6793552016-01-19 14:18:37 -08003120 except AssertionError:
3121 main.log.exception( "" )
3122 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003123 except TypeError:
3124 main.log.exception( self.name + ": Object not as expected" )
3125 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003129 main.cleanup()
3130 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003132 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003133 main.cleanup()
3134 main.exit()
3135
kelvin8ec71442015-01-15 16:57:00 -08003136 def getAllIntentIds( self ):
3137 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003138 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003139 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003140 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003141 cmdStr = "onos:intents | grep id="
3142 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003143 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003144 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003145 if re.search( "Error", output ):
3146 main.log.error( "Error in getting ports" )
3147 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003148 return output
Jon Hallc6793552016-01-19 14:18:37 -08003149 except AssertionError:
3150 main.log.exception( "" )
3151 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003152 except TypeError:
3153 main.log.exception( self.name + ": Object not as expected" )
3154 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003156 main.log.error( self.name + ": EOF exception found" )
3157 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003158 main.cleanup()
3159 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003160 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003161 main.log.exception( self.name + ": Uncaught exception!" )
3162 main.cleanup()
3163 main.exit()
3164
Jon Hall73509952015-02-24 16:42:56 -08003165 def intentSummary( self ):
3166 """
Jon Hallefbd9792015-03-05 16:11:36 -08003167 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003168 """
3169 try:
3170 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003171 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003172 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003173 states.append( intent.get( 'state', None ) )
3174 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003175 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003176 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003177 except ( TypeError, ValueError ):
3178 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003179 return None
3180 except pexpect.EOF:
3181 main.log.error( self.name + ": EOF exception found" )
3182 main.log.error( self.name + ": " + self.handle.before )
3183 main.cleanup()
3184 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003185 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003186 main.log.exception( self.name + ": Uncaught exception!" )
3187 main.cleanup()
3188 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003189
Jon Hall61282e32015-03-19 11:34:11 -07003190 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003191 """
3192 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003193 Optional argument:
3194 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003195 """
Jon Hall63604932015-02-26 17:09:50 -08003196 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003197 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003198 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003199 cmdStr += " -j"
3200 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003201 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003202 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003203 return output
Jon Hallc6793552016-01-19 14:18:37 -08003204 except AssertionError:
3205 main.log.exception( "" )
3206 return None
Jon Hall63604932015-02-26 17:09:50 -08003207 except TypeError:
3208 main.log.exception( self.name + ": Object not as expected" )
3209 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003210 except pexpect.EOF:
3211 main.log.error( self.name + ": EOF exception found" )
3212 main.log.error( self.name + ": " + self.handle.before )
3213 main.cleanup()
3214 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003215 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003216 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003217 main.cleanup()
3218 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003219
acsmarsa4a4d1e2015-07-10 16:01:24 -07003220 def leaderCandidates( self, jsonFormat=True ):
3221 """
3222 Returns the output of the leaders -c command.
3223 Optional argument:
3224 * jsonFormat - boolean indicating if you want output in json
3225 """
3226 try:
3227 cmdStr = "onos:leaders -c"
3228 if jsonFormat:
3229 cmdStr += " -j"
3230 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003231 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003232 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003233 return output
Jon Hallc6793552016-01-19 14:18:37 -08003234 except AssertionError:
3235 main.log.exception( "" )
3236 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003237 except TypeError:
3238 main.log.exception( self.name + ": Object not as expected" )
3239 return None
3240 except pexpect.EOF:
3241 main.log.error( self.name + ": EOF exception found" )
3242 main.log.error( self.name + ": " + self.handle.before )
3243 main.cleanup()
3244 main.exit()
3245 except Exception:
3246 main.log.exception( self.name + ": Uncaught exception!" )
3247 main.cleanup()
3248 main.exit()
3249
Jon Hallc6793552016-01-19 14:18:37 -08003250 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003251 """
3252 Returns a list in format [leader,candidate1,candidate2,...] for a given
3253 topic parameter and an empty list if the topic doesn't exist
3254 If no leader is elected leader in the returned list will be "none"
3255 Returns None if there is a type error processing the json object
3256 """
3257 try:
Jon Hall6e709752016-02-01 13:38:46 -08003258 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003259 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003260 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003261 assert "Command not found:" not in rawOutput, rawOutput
3262 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003263 results = []
3264 for dict in output:
3265 if dict["topic"] == topic:
3266 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003267 candidates = re.split( ", ", dict["candidates"][1:-1] )
3268 results.append( leader )
3269 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003270 return results
Jon Hallc6793552016-01-19 14:18:37 -08003271 except AssertionError:
3272 main.log.exception( "" )
3273 return None
3274 except ( TypeError, ValueError ):
3275 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003276 return None
3277 except pexpect.EOF:
3278 main.log.error( self.name + ": EOF exception found" )
3279 main.log.error( self.name + ": " + self.handle.before )
3280 main.cleanup()
3281 main.exit()
3282 except Exception:
3283 main.log.exception( self.name + ": Uncaught exception!" )
3284 main.cleanup()
3285 main.exit()
3286
Jon Hall61282e32015-03-19 11:34:11 -07003287 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003288 """
3289 Returns the output of the intent Pending map.
3290 """
Jon Hall63604932015-02-26 17:09:50 -08003291 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003292 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003293 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003294 cmdStr += " -j"
3295 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003296 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003297 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003298 return output
Jon Hallc6793552016-01-19 14:18:37 -08003299 except AssertionError:
3300 main.log.exception( "" )
3301 return None
Jon Hall63604932015-02-26 17:09:50 -08003302 except TypeError:
3303 main.log.exception( self.name + ": Object not as expected" )
3304 return None
3305 except pexpect.EOF:
3306 main.log.error( self.name + ": EOF exception found" )
3307 main.log.error( self.name + ": " + self.handle.before )
3308 main.cleanup()
3309 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003310 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003311 main.log.exception( self.name + ": Uncaught exception!" )
3312 main.cleanup()
3313 main.exit()
3314
Jon Hall61282e32015-03-19 11:34:11 -07003315 def partitions( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003316 """
3317 Returns the output of the raft partitions command for ONOS.
3318 """
Jon Hall61282e32015-03-19 11:34:11 -07003319 # Sample JSON
3320 # {
3321 # "leader": "tcp://10.128.30.11:7238",
3322 # "members": [
3323 # "tcp://10.128.30.11:7238",
3324 # "tcp://10.128.30.17:7238",
3325 # "tcp://10.128.30.13:7238",
3326 # ],
3327 # "name": "p1",
3328 # "term": 3
3329 # },
Jon Hall63604932015-02-26 17:09:50 -08003330 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003331 cmdStr = "onos:partitions"
Jon Hall61282e32015-03-19 11:34:11 -07003332 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003333 cmdStr += " -j"
3334 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003335 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003336 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003337 return output
Jon Hallc6793552016-01-19 14:18:37 -08003338 except AssertionError:
3339 main.log.exception( "" )
3340 return None
Jon Hall63604932015-02-26 17:09:50 -08003341 except TypeError:
3342 main.log.exception( self.name + ": Object not as expected" )
3343 return None
3344 except pexpect.EOF:
3345 main.log.error( self.name + ": EOF exception found" )
3346 main.log.error( self.name + ": " + self.handle.before )
3347 main.cleanup()
3348 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003349 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003350 main.log.exception( self.name + ": Uncaught exception!" )
3351 main.cleanup()
3352 main.exit()
3353
Jon Hallbe379602015-03-24 13:39:32 -07003354 def apps( self, jsonFormat=True ):
3355 """
3356 Returns the output of the apps command for ONOS. This command lists
3357 information about installed ONOS applications
3358 """
3359 # Sample JSON object
3360 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3361 # "description":"ONOS OpenFlow protocol southbound providers",
3362 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3363 # "features":"[onos-openflow]","state":"ACTIVE"}]
3364 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003365 cmdStr = "onos:apps"
Jon Hallbe379602015-03-24 13:39:32 -07003366 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003367 cmdStr += " -j"
3368 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003369 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003370 assert "Command not found:" not in output, output
3371 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003372 return output
Jon Hallbe379602015-03-24 13:39:32 -07003373 # FIXME: look at specific exceptions/Errors
3374 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003375 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003376 return None
3377 except TypeError:
3378 main.log.exception( self.name + ": Object not as expected" )
3379 return None
3380 except pexpect.EOF:
3381 main.log.error( self.name + ": EOF exception found" )
3382 main.log.error( self.name + ": " + self.handle.before )
3383 main.cleanup()
3384 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003385 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003386 main.log.exception( self.name + ": Uncaught exception!" )
3387 main.cleanup()
3388 main.exit()
3389
Jon Hall146f1522015-03-24 15:33:24 -07003390 def appStatus( self, appName ):
3391 """
3392 Uses the onos:apps cli command to return the status of an application.
3393 Returns:
3394 "ACTIVE" - If app is installed and activated
3395 "INSTALLED" - If app is installed and deactivated
3396 "UNINSTALLED" - If app is not installed
3397 None - on error
3398 """
Jon Hall146f1522015-03-24 15:33:24 -07003399 try:
3400 if not isinstance( appName, types.StringType ):
3401 main.log.error( self.name + ".appStatus(): appName must be" +
3402 " a string" )
3403 return None
3404 output = self.apps( jsonFormat=True )
3405 appsJson = json.loads( output )
3406 state = None
3407 for app in appsJson:
3408 if appName == app.get('name'):
3409 state = app.get('state')
3410 break
3411 if state == "ACTIVE" or state == "INSTALLED":
3412 return state
3413 elif state is None:
3414 return "UNINSTALLED"
3415 elif state:
3416 main.log.error( "Unexpected state from 'onos:apps': " +
3417 str( state ) )
3418 return state
Jon Hallc6793552016-01-19 14:18:37 -08003419 except ( TypeError, ValueError ):
3420 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003421 return None
3422 except pexpect.EOF:
3423 main.log.error( self.name + ": EOF exception found" )
3424 main.log.error( self.name + ": " + self.handle.before )
3425 main.cleanup()
3426 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003427 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003428 main.log.exception( self.name + ": Uncaught exception!" )
3429 main.cleanup()
3430 main.exit()
3431
Jon Hallbe379602015-03-24 13:39:32 -07003432 def app( self, appName, option ):
3433 """
3434 Interacts with the app command for ONOS. This command manages
3435 application inventory.
3436 """
Jon Hallbe379602015-03-24 13:39:32 -07003437 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003438 # Validate argument types
3439 valid = True
3440 if not isinstance( appName, types.StringType ):
3441 main.log.error( self.name + ".app(): appName must be a " +
3442 "string" )
3443 valid = False
3444 if not isinstance( option, types.StringType ):
3445 main.log.error( self.name + ".app(): option must be a string" )
3446 valid = False
3447 if not valid:
3448 return main.FALSE
3449 # Validate Option
3450 option = option.lower()
3451 # NOTE: Install may become a valid option
3452 if option == "activate":
3453 pass
3454 elif option == "deactivate":
3455 pass
3456 elif option == "uninstall":
3457 pass
3458 else:
3459 # Invalid option
3460 main.log.error( "The ONOS app command argument only takes " +
3461 "the values: (activate|deactivate|uninstall)" +
3462 "; was given '" + option + "'")
3463 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003464 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003465 output = self.sendline( cmdStr )
Jon Hallbe379602015-03-24 13:39:32 -07003466 if "Error executing command" in output:
3467 main.log.error( "Error in processing onos:app command: " +
3468 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003469 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003470 elif "No such application" in output:
3471 main.log.error( "The application '" + appName +
3472 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003473 return main.FALSE
3474 elif "Command not found:" in output:
3475 main.log.error( "Error in processing onos:app command: " +
3476 str( output ) )
3477 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003478 elif "Unsupported command:" in output:
3479 main.log.error( "Incorrect command given to 'app': " +
3480 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003481 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003482 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003483 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003484 return main.TRUE
3485 except TypeError:
3486 main.log.exception( self.name + ": Object not as expected" )
3487 return main.ERROR
3488 except pexpect.EOF:
3489 main.log.error( self.name + ": EOF exception found" )
3490 main.log.error( self.name + ": " + self.handle.before )
3491 main.cleanup()
3492 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003493 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003494 main.log.exception( self.name + ": Uncaught exception!" )
3495 main.cleanup()
3496 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003497
Jon Hallbd16b922015-03-26 17:53:15 -07003498 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003499 """
3500 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003501 appName is the hierarchical app name, not the feature name
3502 If check is True, method will check the status of the app after the
3503 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003504 Returns main.TRUE if the command was successfully sent
3505 main.FALSE if the cli responded with an error or given
3506 incorrect input
3507 """
3508 try:
3509 if not isinstance( appName, types.StringType ):
3510 main.log.error( self.name + ".activateApp(): appName must be" +
3511 " a string" )
3512 return main.FALSE
3513 status = self.appStatus( appName )
3514 if status == "INSTALLED":
3515 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003516 if check and response == main.TRUE:
3517 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003518 status = self.appStatus( appName )
3519 if status == "ACTIVE":
3520 return main.TRUE
3521 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003522 main.log.debug( "The state of application " +
3523 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003524 time.sleep( 1 )
3525 return main.FALSE
3526 else: # not 'check' or command didn't succeed
3527 return response
Jon Hall146f1522015-03-24 15:33:24 -07003528 elif status == "ACTIVE":
3529 return main.TRUE
3530 elif status == "UNINSTALLED":
3531 main.log.error( self.name + ": Tried to activate the " +
3532 "application '" + appName + "' which is not " +
3533 "installed." )
3534 else:
3535 main.log.error( "Unexpected return value from appStatus: " +
3536 str( status ) )
3537 return main.ERROR
3538 except TypeError:
3539 main.log.exception( self.name + ": Object not as expected" )
3540 return main.ERROR
3541 except pexpect.EOF:
3542 main.log.error( self.name + ": EOF exception found" )
3543 main.log.error( self.name + ": " + self.handle.before )
3544 main.cleanup()
3545 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003546 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003547 main.log.exception( self.name + ": Uncaught exception!" )
3548 main.cleanup()
3549 main.exit()
3550
Jon Hallbd16b922015-03-26 17:53:15 -07003551 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003552 """
3553 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003554 appName is the hierarchical app name, not the feature name
3555 If check is True, method will check the status of the app after the
3556 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003557 Returns main.TRUE if the command was successfully sent
3558 main.FALSE if the cli responded with an error or given
3559 incorrect input
3560 """
3561 try:
3562 if not isinstance( appName, types.StringType ):
3563 main.log.error( self.name + ".deactivateApp(): appName must " +
3564 "be a string" )
3565 return main.FALSE
3566 status = self.appStatus( appName )
3567 if status == "INSTALLED":
3568 return main.TRUE
3569 elif status == "ACTIVE":
3570 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003571 if check and response == main.TRUE:
3572 for i in range(10): # try 10 times then give up
3573 status = self.appStatus( appName )
3574 if status == "INSTALLED":
3575 return main.TRUE
3576 else:
3577 time.sleep( 1 )
3578 return main.FALSE
3579 else: # not check or command didn't succeed
3580 return response
Jon Hall146f1522015-03-24 15:33:24 -07003581 elif status == "UNINSTALLED":
3582 main.log.warn( self.name + ": Tried to deactivate the " +
3583 "application '" + appName + "' which is not " +
3584 "installed." )
3585 return main.TRUE
3586 else:
3587 main.log.error( "Unexpected return value from appStatus: " +
3588 str( status ) )
3589 return main.ERROR
3590 except TypeError:
3591 main.log.exception( self.name + ": Object not as expected" )
3592 return main.ERROR
3593 except pexpect.EOF:
3594 main.log.error( self.name + ": EOF exception found" )
3595 main.log.error( self.name + ": " + self.handle.before )
3596 main.cleanup()
3597 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003598 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003599 main.log.exception( self.name + ": Uncaught exception!" )
3600 main.cleanup()
3601 main.exit()
3602
Jon Hallbd16b922015-03-26 17:53:15 -07003603 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003604 """
3605 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003606 appName is the hierarchical app name, not the feature name
3607 If check is True, method will check the status of the app after the
3608 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003609 Returns main.TRUE if the command was successfully sent
3610 main.FALSE if the cli responded with an error or given
3611 incorrect input
3612 """
3613 # TODO: check with Thomas about the state machine for apps
3614 try:
3615 if not isinstance( appName, types.StringType ):
3616 main.log.error( self.name + ".uninstallApp(): appName must " +
3617 "be a string" )
3618 return main.FALSE
3619 status = self.appStatus( appName )
3620 if status == "INSTALLED":
3621 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003622 if check and response == main.TRUE:
3623 for i in range(10): # try 10 times then give up
3624 status = self.appStatus( appName )
3625 if status == "UNINSTALLED":
3626 return main.TRUE
3627 else:
3628 time.sleep( 1 )
3629 return main.FALSE
3630 else: # not check or command didn't succeed
3631 return response
Jon Hall146f1522015-03-24 15:33:24 -07003632 elif status == "ACTIVE":
3633 main.log.warn( self.name + ": Tried to uninstall the " +
3634 "application '" + appName + "' which is " +
3635 "currently active." )
3636 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003637 if check and response == main.TRUE:
3638 for i in range(10): # try 10 times then give up
3639 status = self.appStatus( appName )
3640 if status == "UNINSTALLED":
3641 return main.TRUE
3642 else:
3643 time.sleep( 1 )
3644 return main.FALSE
3645 else: # not check or command didn't succeed
3646 return response
Jon Hall146f1522015-03-24 15:33:24 -07003647 elif status == "UNINSTALLED":
3648 return main.TRUE
3649 else:
3650 main.log.error( "Unexpected return value from appStatus: " +
3651 str( status ) )
3652 return main.ERROR
3653 except TypeError:
3654 main.log.exception( self.name + ": Object not as expected" )
3655 return main.ERROR
3656 except pexpect.EOF:
3657 main.log.error( self.name + ": EOF exception found" )
3658 main.log.error( self.name + ": " + self.handle.before )
3659 main.cleanup()
3660 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003661 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003662 main.log.exception( self.name + ": Uncaught exception!" )
3663 main.cleanup()
3664 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003665
3666 def appIDs( self, jsonFormat=True ):
3667 """
3668 Show the mappings between app id and app names given by the 'app-ids'
3669 cli command
3670 """
3671 try:
3672 cmdStr = "app-ids"
3673 if jsonFormat:
3674 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003675 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003676 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003677 assert "Command not found:" not in output, output
3678 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003679 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003680 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003681 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003682 return None
3683 except TypeError:
3684 main.log.exception( self.name + ": Object not as expected" )
3685 return None
3686 except pexpect.EOF:
3687 main.log.error( self.name + ": EOF exception found" )
3688 main.log.error( self.name + ": " + self.handle.before )
3689 main.cleanup()
3690 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003691 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003692 main.log.exception( self.name + ": Uncaught exception!" )
3693 main.cleanup()
3694 main.exit()
3695
3696 def appToIDCheck( self ):
3697 """
3698 This method will check that each application's ID listed in 'apps' is
3699 the same as the ID listed in 'app-ids'. The check will also check that
3700 there are no duplicate IDs issued. Note that an app ID should be
3701 a globaly unique numerical identifier for app/app-like features. Once
3702 an ID is registered, the ID is never freed up so that if an app is
3703 reinstalled it will have the same ID.
3704
3705 Returns: main.TRUE if the check passes and
3706 main.FALSE if the check fails or
3707 main.ERROR if there is some error in processing the test
3708 """
3709 try:
Jon Hall390696c2015-05-05 17:13:41 -07003710 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003711 rawJson = self.appIDs( jsonFormat=True )
3712 if rawJson:
3713 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003714 else:
Jon Hallc6793552016-01-19 14:18:37 -08003715 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003716 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003717 rawJson = self.apps( jsonFormat=True )
3718 if rawJson:
3719 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003720 else:
Jon Hallc6793552016-01-19 14:18:37 -08003721 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003722 bail = True
3723 if bail:
3724 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003725 result = main.TRUE
3726 for app in apps:
3727 appID = app.get( 'id' )
3728 if appID is None:
3729 main.log.error( "Error parsing app: " + str( app ) )
3730 result = main.FALSE
3731 appName = app.get( 'name' )
3732 if appName is None:
3733 main.log.error( "Error parsing app: " + str( app ) )
3734 result = main.FALSE
3735 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003736 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003737 # main.log.debug( "Comparing " + str( app ) + " to " +
3738 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003739 if not current: # if ids doesn't have this id
3740 result = main.FALSE
3741 main.log.error( "'app-ids' does not have the ID for " +
3742 str( appName ) + " that apps does." )
3743 elif len( current ) > 1:
3744 # there is more than one app with this ID
3745 result = main.FALSE
3746 # We will log this later in the method
3747 elif not current[0][ 'name' ] == appName:
3748 currentName = current[0][ 'name' ]
3749 result = main.FALSE
3750 main.log.error( "'app-ids' has " + str( currentName ) +
3751 " registered under id:" + str( appID ) +
3752 " but 'apps' has " + str( appName ) )
3753 else:
3754 pass # id and name match!
3755 # now make sure that app-ids has no duplicates
3756 idsList = []
3757 namesList = []
3758 for item in ids:
3759 idsList.append( item[ 'id' ] )
3760 namesList.append( item[ 'name' ] )
3761 if len( idsList ) != len( set( idsList ) ) or\
3762 len( namesList ) != len( set( namesList ) ):
3763 main.log.error( "'app-ids' has some duplicate entries: \n"
3764 + json.dumps( ids,
3765 sort_keys=True,
3766 indent=4,
3767 separators=( ',', ': ' ) ) )
3768 result = main.FALSE
3769 return result
Jon Hallc6793552016-01-19 14:18:37 -08003770 except ( TypeError, ValueError ):
3771 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003772 return main.ERROR
3773 except pexpect.EOF:
3774 main.log.error( self.name + ": EOF exception found" )
3775 main.log.error( self.name + ": " + self.handle.before )
3776 main.cleanup()
3777 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003778 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003779 main.log.exception( self.name + ": Uncaught exception!" )
3780 main.cleanup()
3781 main.exit()
3782
Jon Hallfb760a02015-04-13 15:35:03 -07003783 def getCfg( self, component=None, propName=None, short=False,
3784 jsonFormat=True ):
3785 """
3786 Get configuration settings from onos cli
3787 Optional arguments:
3788 component - Optionally only list configurations for a specific
3789 component. If None, all components with configurations
3790 are displayed. Case Sensitive string.
3791 propName - If component is specified, propName option will show
3792 only this specific configuration from that component.
3793 Case Sensitive string.
3794 jsonFormat - Returns output as json. Note that this will override
3795 the short option
3796 short - Short, less verbose, version of configurations.
3797 This is overridden by the json option
3798 returns:
3799 Output from cli as a string or None on error
3800 """
3801 try:
3802 baseStr = "cfg"
3803 cmdStr = " get"
3804 componentStr = ""
3805 if component:
3806 componentStr += " " + component
3807 if propName:
3808 componentStr += " " + propName
3809 if jsonFormat:
3810 baseStr += " -j"
3811 elif short:
3812 baseStr += " -s"
3813 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003814 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003815 assert "Command not found:" not in output, output
3816 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003817 return output
3818 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003819 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003820 return None
3821 except TypeError:
3822 main.log.exception( self.name + ": Object not as expected" )
3823 return None
3824 except pexpect.EOF:
3825 main.log.error( self.name + ": EOF exception found" )
3826 main.log.error( self.name + ": " + self.handle.before )
3827 main.cleanup()
3828 main.exit()
3829 except Exception:
3830 main.log.exception( self.name + ": Uncaught exception!" )
3831 main.cleanup()
3832 main.exit()
3833
3834 def setCfg( self, component, propName, value=None, check=True ):
3835 """
3836 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003837 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003838 component - The case sensitive name of the component whose
3839 property is to be set
3840 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003841 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003842 value - The value to set the property to. If None, will unset the
3843 property and revert it to it's default value(if applicable)
3844 check - Boolean, Check whether the option was successfully set this
3845 only applies when a value is given.
3846 returns:
3847 main.TRUE on success or main.FALSE on failure. If check is False,
3848 will return main.TRUE unless there is an error
3849 """
3850 try:
3851 baseStr = "cfg"
3852 cmdStr = " set " + str( component ) + " " + str( propName )
3853 if value is not None:
3854 cmdStr += " " + str( value )
3855 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003856 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003857 assert "Command not found:" not in output, output
3858 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003859 if value and check:
3860 results = self.getCfg( component=str( component ),
3861 propName=str( propName ),
3862 jsonFormat=True )
3863 # Check if current value is what we just set
3864 try:
3865 jsonOutput = json.loads( results )
3866 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003867 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003868 main.log.exception( "Error parsing cfg output" )
3869 main.log.error( "output:" + repr( results ) )
3870 return main.FALSE
3871 if current == str( value ):
3872 return main.TRUE
3873 return main.FALSE
3874 return main.TRUE
3875 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003876 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003877 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003878 except ( TypeError, ValueError ):
3879 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003880 return main.FALSE
3881 except pexpect.EOF:
3882 main.log.error( self.name + ": EOF exception found" )
3883 main.log.error( self.name + ": " + self.handle.before )
3884 main.cleanup()
3885 main.exit()
3886 except Exception:
3887 main.log.exception( self.name + ": Uncaught exception!" )
3888 main.cleanup()
3889 main.exit()
3890
Jon Hall390696c2015-05-05 17:13:41 -07003891 def setTestAdd( self, setName, values ):
3892 """
3893 CLI command to add elements to a distributed set.
3894 Arguments:
3895 setName - The name of the set to add to.
3896 values - The value(s) to add to the set, space seperated.
3897 Example usages:
3898 setTestAdd( "set1", "a b c" )
3899 setTestAdd( "set2", "1" )
3900 returns:
3901 main.TRUE on success OR
3902 main.FALSE if elements were already in the set OR
3903 main.ERROR on error
3904 """
3905 try:
3906 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
3907 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003908 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003909 assert "Command not found:" not in output, output
Jon Hallfeff3082015-05-19 10:23:26 -07003910 try:
3911 # TODO: Maybe make this less hardcoded
3912 # ConsistentMap Exceptions
3913 assert "org.onosproject.store.service" not in output
3914 # Node not leader
3915 assert "java.lang.IllegalStateException" not in output
3916 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003917 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003918 "command: " + str( output ) )
3919 retryTime = 30 # Conservative time, given by Madan
3920 main.log.info( "Waiting " + str( retryTime ) +
3921 "seconds before retrying." )
3922 time.sleep( retryTime ) # Due to change in mastership
3923 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003924 assert output is not None, "Error in sendline"
Jon Hall390696c2015-05-05 17:13:41 -07003925 assert "Error executing command" not in output
3926 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3927 negativeMatch = "\[(.*)\] was already in set " + str( setName )
3928 main.log.info( self.name + ": " + output )
3929 if re.search( positiveMatch, output):
3930 return main.TRUE
3931 elif re.search( negativeMatch, output):
3932 return main.FALSE
3933 else:
3934 main.log.error( self.name + ": setTestAdd did not" +
3935 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07003936 main.log.debug( self.name + " actual: " + repr( output ) )
3937 return main.ERROR
3938 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003939 main.log.exception( "Error in processing '" + cmdStr + "' command. " )
Jon Hall390696c2015-05-05 17:13:41 -07003940 return main.ERROR
3941 except TypeError:
3942 main.log.exception( self.name + ": Object not as expected" )
3943 return main.ERROR
3944 except pexpect.EOF:
3945 main.log.error( self.name + ": EOF exception found" )
3946 main.log.error( self.name + ": " + self.handle.before )
3947 main.cleanup()
3948 main.exit()
3949 except Exception:
3950 main.log.exception( self.name + ": Uncaught exception!" )
3951 main.cleanup()
3952 main.exit()
3953
3954 def setTestRemove( self, setName, values, clear=False, retain=False ):
3955 """
3956 CLI command to remove elements from a distributed set.
3957 Required arguments:
3958 setName - The name of the set to remove from.
3959 values - The value(s) to remove from the set, space seperated.
3960 Optional arguments:
3961 clear - Clear all elements from the set
3962 retain - Retain only the given values. (intersection of the
3963 original set and the given set)
3964 returns:
3965 main.TRUE on success OR
3966 main.FALSE if the set was not changed OR
3967 main.ERROR on error
3968 """
3969 try:
3970 cmdStr = "set-test-remove "
3971 if clear:
3972 cmdStr += "-c " + str( setName )
3973 elif retain:
3974 cmdStr += "-r " + str( setName ) + " " + str( values )
3975 else:
3976 cmdStr += str( setName ) + " " + str( values )
3977 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07003978 try:
Jon Halla495f562016-05-16 18:03:26 -07003979 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07003980 # TODO: Maybe make this less hardcoded
3981 # ConsistentMap Exceptions
3982 assert "org.onosproject.store.service" not in output
3983 # Node not leader
3984 assert "java.lang.IllegalStateException" not in output
3985 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07003986 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07003987 "command: " + str( output ) )
3988 retryTime = 30 # Conservative time, given by Madan
3989 main.log.info( "Waiting " + str( retryTime ) +
3990 "seconds before retrying." )
3991 time.sleep( retryTime ) # Due to change in mastership
3992 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003993 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003994 assert "Command not found:" not in output, output
3995 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07003996 main.log.info( self.name + ": " + output )
3997 if clear:
3998 pattern = "Set " + str( setName ) + " cleared"
3999 if re.search( pattern, output ):
4000 return main.TRUE
4001 elif retain:
4002 positivePattern = str( setName ) + " was pruned to contain " +\
4003 "only elements of set \[(.*)\]"
4004 negativePattern = str( setName ) + " was not changed by " +\
4005 "retaining only elements of the set " +\
4006 "\[(.*)\]"
4007 if re.search( positivePattern, output ):
4008 return main.TRUE
4009 elif re.search( negativePattern, output ):
4010 return main.FALSE
4011 else:
4012 positivePattern = "\[(.*)\] was removed from the set " +\
4013 str( setName )
4014 if ( len( values.split() ) == 1 ):
4015 negativePattern = "\[(.*)\] was not in set " +\
4016 str( setName )
4017 else:
4018 negativePattern = "No element of \[(.*)\] was in set " +\
4019 str( setName )
4020 if re.search( positivePattern, output ):
4021 return main.TRUE
4022 elif re.search( negativePattern, output ):
4023 return main.FALSE
4024 main.log.error( self.name + ": setTestRemove did not" +
4025 " match expected output" )
4026 main.log.debug( self.name + " expected: " + pattern )
4027 main.log.debug( self.name + " actual: " + repr( output ) )
4028 return main.ERROR
4029 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004030 main.log.exception( "Error in processing '" + cmdStr + "' commandr. " )
Jon Hall390696c2015-05-05 17:13:41 -07004031 return main.ERROR
4032 except TypeError:
4033 main.log.exception( self.name + ": Object not as expected" )
4034 return main.ERROR
4035 except pexpect.EOF:
4036 main.log.error( self.name + ": EOF exception found" )
4037 main.log.error( self.name + ": " + self.handle.before )
4038 main.cleanup()
4039 main.exit()
4040 except Exception:
4041 main.log.exception( self.name + ": Uncaught exception!" )
4042 main.cleanup()
4043 main.exit()
4044
4045 def setTestGet( self, setName, values="" ):
4046 """
4047 CLI command to get the elements in a distributed set.
4048 Required arguments:
4049 setName - The name of the set to remove from.
4050 Optional arguments:
4051 values - The value(s) to check if in the set, space seperated.
4052 returns:
4053 main.ERROR on error OR
4054 A list of elements in the set if no optional arguments are
4055 supplied OR
4056 A tuple containing the list then:
4057 main.FALSE if the given values are not in the set OR
4058 main.TRUE if the given values are in the set OR
4059 """
4060 try:
4061 values = str( values ).strip()
4062 setName = str( setName ).strip()
4063 length = len( values.split() )
4064 containsCheck = None
4065 # Patterns to match
4066 setPattern = "\[(.*)\]"
4067 pattern = "Items in set " + setName + ":\n" + setPattern
4068 containsTrue = "Set " + setName + " contains the value " + values
4069 containsFalse = "Set " + setName + " did not contain the value " +\
4070 values
4071 containsAllTrue = "Set " + setName + " contains the the subset " +\
4072 setPattern
4073 containsAllFalse = "Set " + setName + " did not contain the the" +\
4074 " subset " + setPattern
4075
4076 cmdStr = "set-test-get "
4077 cmdStr += setName + " " + values
4078 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004079 try:
Jon Halla495f562016-05-16 18:03:26 -07004080 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004081 # TODO: Maybe make this less hardcoded
4082 # ConsistentMap Exceptions
4083 assert "org.onosproject.store.service" not in output
4084 # Node not leader
4085 assert "java.lang.IllegalStateException" not in output
4086 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004087 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004088 "command: " + str( output ) )
4089 retryTime = 30 # Conservative time, given by Madan
4090 main.log.info( "Waiting " + str( retryTime ) +
4091 "seconds before retrying." )
4092 time.sleep( retryTime ) # Due to change in mastership
4093 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004094 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004095 assert "Command not found:" not in output, output
4096 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004097 main.log.info( self.name + ": " + output )
4098
4099 if length == 0:
4100 match = re.search( pattern, output )
4101 else: # if given values
4102 if length == 1: # Contains output
4103 patternTrue = pattern + "\n" + containsTrue
4104 patternFalse = pattern + "\n" + containsFalse
4105 else: # ContainsAll output
4106 patternTrue = pattern + "\n" + containsAllTrue
4107 patternFalse = pattern + "\n" + containsAllFalse
4108 matchTrue = re.search( patternTrue, output )
4109 matchFalse = re.search( patternFalse, output )
4110 if matchTrue:
4111 containsCheck = main.TRUE
4112 match = matchTrue
4113 elif matchFalse:
4114 containsCheck = main.FALSE
4115 match = matchFalse
4116 else:
4117 main.log.error( self.name + " setTestGet did not match " +\
4118 "expected output" )
4119 main.log.debug( self.name + " expected: " + pattern )
4120 main.log.debug( self.name + " actual: " + repr( output ) )
4121 match = None
4122 if match:
4123 setMatch = match.group( 1 )
4124 if setMatch == '':
4125 setList = []
4126 else:
4127 setList = setMatch.split( ", " )
4128 if length > 0:
4129 return ( setList, containsCheck )
4130 else:
4131 return setList
4132 else: # no match
4133 main.log.error( self.name + ": setTestGet did not" +
4134 " match expected output" )
4135 main.log.debug( self.name + " expected: " + pattern )
4136 main.log.debug( self.name + " actual: " + repr( output ) )
4137 return main.ERROR
4138 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004139 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004140 return main.ERROR
4141 except TypeError:
4142 main.log.exception( self.name + ": Object not as expected" )
4143 return main.ERROR
4144 except pexpect.EOF:
4145 main.log.error( self.name + ": EOF exception found" )
4146 main.log.error( self.name + ": " + self.handle.before )
4147 main.cleanup()
4148 main.exit()
4149 except Exception:
4150 main.log.exception( self.name + ": Uncaught exception!" )
4151 main.cleanup()
4152 main.exit()
4153
4154 def setTestSize( self, setName ):
4155 """
4156 CLI command to get the elements in a distributed set.
4157 Required arguments:
4158 setName - The name of the set to remove from.
4159 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004160 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004161 None on error
4162 """
4163 try:
4164 # TODO: Should this check against the number of elements returned
4165 # and then return true/false based on that?
4166 setName = str( setName ).strip()
4167 # Patterns to match
4168 setPattern = "\[(.*)\]"
4169 pattern = "There are (\d+) items in set " + setName + ":\n" +\
4170 setPattern
4171 cmdStr = "set-test-get -s "
4172 cmdStr += setName
4173 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004174 try:
Jon Halla495f562016-05-16 18:03:26 -07004175 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004176 # TODO: Maybe make this less hardcoded
4177 # ConsistentMap Exceptions
4178 assert "org.onosproject.store.service" not in output
4179 # Node not leader
4180 assert "java.lang.IllegalStateException" not in output
4181 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004182 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004183 "command: " + str( output ) )
4184 retryTime = 30 # Conservative time, given by Madan
4185 main.log.info( "Waiting " + str( retryTime ) +
4186 "seconds before retrying." )
4187 time.sleep( retryTime ) # Due to change in mastership
4188 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004189 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004190 assert "Command not found:" not in output, output
4191 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004192 main.log.info( self.name + ": " + output )
4193 match = re.search( pattern, output )
4194 if match:
4195 setSize = int( match.group( 1 ) )
4196 setMatch = match.group( 2 )
4197 if len( setMatch.split() ) == setSize:
4198 main.log.info( "The size returned by " + self.name +
4199 " matches the number of elements in " +
4200 "the returned set" )
4201 else:
4202 main.log.error( "The size returned by " + self.name +
4203 " does not match the number of " +
4204 "elements in the returned set." )
4205 return setSize
4206 else: # no match
4207 main.log.error( self.name + ": setTestGet did not" +
4208 " match expected output" )
4209 main.log.debug( self.name + " expected: " + pattern )
4210 main.log.debug( self.name + " actual: " + repr( output ) )
4211 return None
4212 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004213 main.log.exception( "Error in processing '" + cmdStr + "' command." )
acsmarsa4a4d1e2015-07-10 16:01:24 -07004214 return None
Jon Hall390696c2015-05-05 17:13:41 -07004215 except TypeError:
4216 main.log.exception( self.name + ": Object not as expected" )
4217 return None
4218 except pexpect.EOF:
4219 main.log.error( self.name + ": EOF exception found" )
4220 main.log.error( self.name + ": " + self.handle.before )
4221 main.cleanup()
4222 main.exit()
4223 except Exception:
4224 main.log.exception( self.name + ": Uncaught exception!" )
4225 main.cleanup()
4226 main.exit()
4227
Jon Hall80daded2015-05-27 16:07:00 -07004228 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004229 """
4230 Command to list the various counters in the system.
4231 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004232 if jsonFormat, a string of the json object returned by the cli
4233 command
4234 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004235 None on error
4236 """
Jon Hall390696c2015-05-05 17:13:41 -07004237 try:
4238 counters = {}
4239 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004240 if jsonFormat:
4241 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004242 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004243 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004244 assert "Command not found:" not in output, output
4245 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004246 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004247 return output
Jon Hall390696c2015-05-05 17:13:41 -07004248 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004249 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004250 return None
Jon Hall390696c2015-05-05 17:13:41 -07004251 except TypeError:
4252 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004253 return None
Jon Hall390696c2015-05-05 17:13:41 -07004254 except pexpect.EOF:
4255 main.log.error( self.name + ": EOF exception found" )
4256 main.log.error( self.name + ": " + self.handle.before )
4257 main.cleanup()
4258 main.exit()
4259 except Exception:
4260 main.log.exception( self.name + ": Uncaught exception!" )
4261 main.cleanup()
4262 main.exit()
4263
Jon Hall935db192016-04-19 00:22:04 -07004264 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004265 """
Jon Halle1a3b752015-07-22 13:02:46 -07004266 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004267 Required arguments:
4268 counter - The name of the counter to increment.
4269 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004270 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004271 returns:
4272 integer value of the counter or
4273 None on Error
4274 """
4275 try:
4276 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004277 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004278 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004279 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004280 if delta != 1:
4281 cmdStr += " " + str( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004282 output = self.sendline( cmdStr )
Jon Hallfeff3082015-05-19 10:23:26 -07004283 try:
Jon Halla495f562016-05-16 18:03:26 -07004284 assert output is not None, "Error in sendline"
Jon Hallfeff3082015-05-19 10:23:26 -07004285 # TODO: Maybe make this less hardcoded
4286 # ConsistentMap Exceptions
4287 assert "org.onosproject.store.service" not in output
4288 # Node not leader
4289 assert "java.lang.IllegalStateException" not in output
4290 except AssertionError:
Jon Halle1a3b752015-07-22 13:02:46 -07004291 main.log.error( "Error in processing '" + cmdStr + "' " +
Jon Hallfeff3082015-05-19 10:23:26 -07004292 "command: " + str( output ) )
4293 retryTime = 30 # Conservative time, given by Madan
4294 main.log.info( "Waiting " + str( retryTime ) +
4295 "seconds before retrying." )
4296 time.sleep( retryTime ) # Due to change in mastership
4297 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004298 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004299 assert "Command not found:" not in output, output
4300 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004301 main.log.info( self.name + ": " + output )
Jon Halle1a3b752015-07-22 13:02:46 -07004302 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004303 match = re.search( pattern, output )
4304 if match:
4305 return int( match.group( 1 ) )
4306 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004307 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004308 " match expected output." )
4309 main.log.debug( self.name + " expected: " + pattern )
4310 main.log.debug( self.name + " actual: " + repr( output ) )
4311 return None
4312 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004313 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Hall390696c2015-05-05 17:13:41 -07004314 return None
4315 except TypeError:
4316 main.log.exception( self.name + ": Object not as expected" )
4317 return None
4318 except pexpect.EOF:
4319 main.log.error( self.name + ": EOF exception found" )
4320 main.log.error( self.name + ": " + self.handle.before )
4321 main.cleanup()
4322 main.exit()
4323 except Exception:
4324 main.log.exception( self.name + ": Uncaught exception!" )
4325 main.cleanup()
4326 main.exit()
4327
Jon Hall935db192016-04-19 00:22:04 -07004328 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004329 """
4330 CLI command to get a distributed counter then add a delta to it.
4331 Required arguments:
4332 counter - The name of the counter to increment.
4333 Optional arguments:
4334 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004335 returns:
4336 integer value of the counter or
4337 None on Error
4338 """
4339 try:
4340 counter = str( counter )
4341 delta = int( delta )
4342 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004343 cmdStr += counter
4344 if delta != 1:
4345 cmdStr += " " + str( delta )
4346 output = self.sendline( cmdStr )
4347 try:
Jon Halla495f562016-05-16 18:03:26 -07004348 assert output is not None, "Error in sendline"
Jon Halle1a3b752015-07-22 13:02:46 -07004349 # TODO: Maybe make this less hardcoded
4350 # ConsistentMap Exceptions
4351 assert "org.onosproject.store.service" not in output
4352 # Node not leader
4353 assert "java.lang.IllegalStateException" not in output
4354 except AssertionError:
4355 main.log.error( "Error in processing '" + cmdStr + "' " +
4356 "command: " + str( output ) )
4357 retryTime = 30 # Conservative time, given by Madan
4358 main.log.info( "Waiting " + str( retryTime ) +
4359 "seconds before retrying." )
4360 time.sleep( retryTime ) # Due to change in mastership
4361 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004362 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004363 assert "Command not found:" not in output, output
4364 assert "Error executing command" not in output, output
Jon Halle1a3b752015-07-22 13:02:46 -07004365 main.log.info( self.name + ": " + output )
4366 pattern = counter + " was updated to (-?\d+)"
4367 match = re.search( pattern, output )
4368 if match:
4369 return int( match.group( 1 ) )
4370 else:
4371 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4372 " match expected output." )
4373 main.log.debug( self.name + " expected: " + pattern )
4374 main.log.debug( self.name + " actual: " + repr( output ) )
4375 return None
4376 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004377 main.log.exception( "Error in processing '" + cmdStr + "' command." )
Jon Halle1a3b752015-07-22 13:02:46 -07004378 return None
4379 except TypeError:
4380 main.log.exception( self.name + ": Object not as expected" )
4381 return None
4382 except pexpect.EOF:
4383 main.log.error( self.name + ": EOF exception found" )
4384 main.log.error( self.name + ": " + self.handle.before )
4385 main.cleanup()
4386 main.exit()
4387 except Exception:
4388 main.log.exception( self.name + ": Uncaught exception!" )
4389 main.cleanup()
4390 main.exit()
4391
YPZhangfebf7302016-05-24 16:45:56 -07004392 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004393 """
4394 Description: Execute summary command in onos
4395 Returns: json object ( summary -j ), returns main.FALSE if there is
4396 no output
4397
4398 """
4399 try:
4400 cmdStr = "summary"
4401 if jsonFormat:
4402 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004403 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004404 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004405 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004406 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004407 if not handle:
4408 main.log.error( self.name + ": There is no output in " +
4409 "summary command" )
4410 return main.FALSE
4411 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004412 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004413 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004414 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004415 except TypeError:
4416 main.log.exception( self.name + ": Object not as expected" )
4417 return None
4418 except pexpect.EOF:
4419 main.log.error( self.name + ": EOF exception found" )
4420 main.log.error( self.name + ": " + self.handle.before )
4421 main.cleanup()
4422 main.exit()
4423 except Exception:
4424 main.log.exception( self.name + ": Uncaught exception!" )
4425 main.cleanup()
4426 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004427
Jon Hall935db192016-04-19 00:22:04 -07004428 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004429 """
4430 CLI command to get the value of a key in a consistent map using
4431 transactions. This a test function and can only get keys from the
4432 test map hard coded into the cli command
4433 Required arguments:
4434 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004435 returns:
4436 The string value of the key or
4437 None on Error
4438 """
4439 try:
4440 keyName = str( keyName )
4441 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004442 cmdStr += keyName
4443 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004444 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004445 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004446 try:
4447 # TODO: Maybe make this less hardcoded
4448 # ConsistentMap Exceptions
4449 assert "org.onosproject.store.service" not in output
4450 # Node not leader
4451 assert "java.lang.IllegalStateException" not in output
4452 except AssertionError:
4453 main.log.error( "Error in processing '" + cmdStr + "' " +
4454 "command: " + str( output ) )
4455 return None
4456 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4457 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004458 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004459 return None
4460 else:
4461 match = re.search( pattern, output )
4462 if match:
4463 return match.groupdict()[ 'value' ]
4464 else:
4465 main.log.error( self.name + ": transactionlMapGet did not" +
4466 " match expected output." )
4467 main.log.debug( self.name + " expected: " + pattern )
4468 main.log.debug( self.name + " actual: " + repr( output ) )
4469 return None
Jon Hallc6793552016-01-19 14:18:37 -08004470 except AssertionError:
4471 main.log.exception( "" )
4472 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004473 except TypeError:
4474 main.log.exception( self.name + ": Object not as expected" )
4475 return None
4476 except pexpect.EOF:
4477 main.log.error( self.name + ": EOF exception found" )
4478 main.log.error( self.name + ": " + self.handle.before )
4479 main.cleanup()
4480 main.exit()
4481 except Exception:
4482 main.log.exception( self.name + ": Uncaught exception!" )
4483 main.cleanup()
4484 main.exit()
4485
Jon Hall935db192016-04-19 00:22:04 -07004486 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004487 """
4488 CLI command to put a value into 'numKeys' number of keys in a
4489 consistent map using transactions. This a test function and can only
4490 put into keys named 'Key#' of the test map hard coded into the cli command
4491 Required arguments:
4492 numKeys - Number of keys to add the value to
4493 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004494 returns:
4495 A dictionary whose keys are the name of the keys put into the map
4496 and the values of the keys are dictionaries whose key-values are
4497 'value': value put into map and optionaly
4498 'oldValue': Previous value in the key or
4499 None on Error
4500
4501 Example output
4502 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4503 'Key2': {'value': 'Testing'} }
4504 """
4505 try:
4506 numKeys = str( numKeys )
4507 value = str( value )
4508 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004509 cmdStr += numKeys + " " + value
4510 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004511 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004512 assert "Command not found:" not in output, output
Jon Hall2a5002c2015-08-21 16:49:11 -07004513 try:
4514 # TODO: Maybe make this less hardcoded
4515 # ConsistentMap Exceptions
4516 assert "org.onosproject.store.service" not in output
4517 # Node not leader
4518 assert "java.lang.IllegalStateException" not in output
4519 except AssertionError:
4520 main.log.error( "Error in processing '" + cmdStr + "' " +
4521 "command: " + str( output ) )
4522 return None
4523 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4524 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4525 results = {}
4526 for line in output.splitlines():
4527 new = re.search( newPattern, line )
4528 updated = re.search( updatedPattern, line )
4529 if new:
4530 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4531 elif updated:
4532 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004533 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004534 else:
4535 main.log.error( self.name + ": transactionlMapGet did not" +
4536 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004537 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4538 newPattern,
4539 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004540 main.log.debug( self.name + " actual: " + repr( output ) )
4541 return results
Jon Hallc6793552016-01-19 14:18:37 -08004542 except AssertionError:
4543 main.log.exception( "" )
4544 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004545 except TypeError:
4546 main.log.exception( self.name + ": Object not as expected" )
4547 return None
4548 except pexpect.EOF:
4549 main.log.error( self.name + ": EOF exception found" )
4550 main.log.error( self.name + ": " + self.handle.before )
4551 main.cleanup()
4552 main.exit()
4553 except Exception:
4554 main.log.exception( self.name + ": Uncaught exception!" )
4555 main.cleanup()
4556 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004557
acsmarsdaea66c2015-09-03 11:44:06 -07004558 def maps( self, jsonFormat=True ):
4559 """
4560 Description: Returns result of onos:maps
4561 Optional:
4562 * jsonFormat: enable json formatting of output
4563 """
4564 try:
4565 cmdStr = "maps"
4566 if jsonFormat:
4567 cmdStr += " -j"
4568 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004569 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004570 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004571 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004572 except AssertionError:
4573 main.log.exception( "" )
4574 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004575 except TypeError:
4576 main.log.exception( self.name + ": Object not as expected" )
4577 return None
4578 except pexpect.EOF:
4579 main.log.error( self.name + ": EOF exception found" )
4580 main.log.error( self.name + ": " + self.handle.before )
4581 main.cleanup()
4582 main.exit()
4583 except Exception:
4584 main.log.exception( self.name + ": Uncaught exception!" )
4585 main.cleanup()
4586 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004587
4588 def getSwController( self, uri, jsonFormat=True ):
4589 """
4590 Descrition: Gets the controller information from the device
4591 """
4592 try:
4593 cmd = "device-controllers "
4594 if jsonFormat:
4595 cmd += "-j "
4596 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004597 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004598 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004599 return response
Jon Hallc6793552016-01-19 14:18:37 -08004600 except AssertionError:
4601 main.log.exception( "" )
4602 return None
GlennRC050596c2015-11-18 17:06:41 -08004603 except TypeError:
4604 main.log.exception( self.name + ": Object not as expected" )
4605 return None
4606 except pexpect.EOF:
4607 main.log.error( self.name + ": EOF exception found" )
4608 main.log.error( self.name + ": " + self.handle.before )
4609 main.cleanup()
4610 main.exit()
4611 except Exception:
4612 main.log.exception( self.name + ": Uncaught exception!" )
4613 main.cleanup()
4614 main.exit()
4615
4616 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4617 """
4618 Descrition: sets the controller(s) for the specified device
4619
4620 Parameters:
4621 Required: uri - String: The uri of the device(switch).
4622 ip - String or List: The ip address of the controller.
4623 This parameter can be formed in a couple of different ways.
4624 VALID:
4625 10.0.0.1 - just the ip address
4626 tcp:10.0.0.1 - the protocol and the ip address
4627 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4628 so that you can add controllers with different
4629 protocols and ports
4630 INVALID:
4631 10.0.0.1:6653 - this is not supported by ONOS
4632
4633 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4634 port - The port number.
4635 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4636
4637 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4638 """
4639 try:
4640 cmd = "device-setcontrollers"
4641
4642 if jsonFormat:
4643 cmd += " -j"
4644 cmd += " " + uri
4645 if isinstance( ip, str ):
4646 ip = [ip]
4647 for item in ip:
4648 if ":" in item:
4649 sitem = item.split( ":" )
4650 if len(sitem) == 3:
4651 cmd += " " + item
4652 elif "." in sitem[1]:
4653 cmd += " {}:{}".format(item, port)
4654 else:
4655 main.log.error( "Malformed entry: " + item )
4656 raise TypeError
4657 else:
4658 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004659 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004660 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004661 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004662 if "Error" in response:
4663 main.log.error( response )
4664 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004665 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004666 except AssertionError:
4667 main.log.exception( "" )
4668 return None
GlennRC050596c2015-11-18 17:06:41 -08004669 except TypeError:
4670 main.log.exception( self.name + ": Object not as expected" )
4671 return main.FALSE
4672 except pexpect.EOF:
4673 main.log.error( self.name + ": EOF exception found" )
4674 main.log.error( self.name + ": " + self.handle.before )
4675 main.cleanup()
4676 main.exit()
4677 except Exception:
4678 main.log.exception( self.name + ": Uncaught exception!" )
4679 main.cleanup()
4680 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004681
4682 def removeDevice( self, device ):
4683 '''
4684 Description:
4685 Remove a device from ONOS by passing the uri of the device(s).
4686 Parameters:
4687 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4688 Returns:
4689 Returns main.FALSE if an exception is thrown or an error is present
4690 in the response. Otherwise, returns main.TRUE.
4691 NOTE:
4692 If a host cannot be removed, then this function will return main.FALSE
4693 '''
4694 try:
4695 if type( device ) is str:
4696 device = list( device )
4697
4698 for d in device:
4699 time.sleep( 1 )
4700 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004701 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004702 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004703 if "Error" in response:
4704 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4705 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004706 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004707 except AssertionError:
4708 main.log.exception( "" )
4709 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004710 except TypeError:
4711 main.log.exception( self.name + ": Object not as expected" )
4712 return main.FALSE
4713 except pexpect.EOF:
4714 main.log.error( self.name + ": EOF exception found" )
4715 main.log.error( self.name + ": " + self.handle.before )
4716 main.cleanup()
4717 main.exit()
4718 except Exception:
4719 main.log.exception( self.name + ": Uncaught exception!" )
4720 main.cleanup()
4721 main.exit()
4722
4723 def removeHost( self, host ):
4724 '''
4725 Description:
4726 Remove a host from ONOS by passing the id of the host(s)
4727 Parameters:
4728 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4729 Returns:
4730 Returns main.FALSE if an exception is thrown or an error is present
4731 in the response. Otherwise, returns main.TRUE.
4732 NOTE:
4733 If a host cannot be removed, then this function will return main.FALSE
4734 '''
4735 try:
4736 if type( host ) is str:
4737 host = list( host )
4738
4739 for h in host:
4740 time.sleep( 1 )
4741 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004742 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004743 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004744 if "Error" in response:
4745 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4746 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004747 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004748 except AssertionError:
4749 main.log.exception( "" )
4750 return None
GlennRC20fc6522015-12-23 23:26:57 -08004751 except TypeError:
4752 main.log.exception( self.name + ": Object not as expected" )
4753 return main.FALSE
4754 except pexpect.EOF:
4755 main.log.error( self.name + ": EOF exception found" )
4756 main.log.error( self.name + ": " + self.handle.before )
4757 main.cleanup()
4758 main.exit()
4759 except Exception:
4760 main.log.exception( self.name + ": Uncaught exception!" )
4761 main.cleanup()
4762 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004763
YPZhangfebf7302016-05-24 16:45:56 -07004764 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004765 '''
4766 Description:
4767 Bring link down or up in the null-provider.
4768 params:
4769 begin - (string) One end of a device or switch.
4770 end - (string) the other end of the device or switch
4771 returns:
4772 main.TRUE if no exceptions were thrown and no Errors are
4773 present in the resoponse. Otherwise, returns main.FALSE
4774 '''
4775 try:
Jon Hallc6793552016-01-19 14:18:37 -08004776 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004777 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004778 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004779 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004780 if "Error" in response or "Failure" in response:
4781 main.log.error( response )
4782 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004784 except AssertionError:
4785 main.log.exception( "" )
4786 return None
GlennRCed771242016-01-13 17:02:47 -08004787 except TypeError:
4788 main.log.exception( self.name + ": Object not as expected" )
4789 return main.FALSE
4790 except pexpect.EOF:
4791 main.log.error( self.name + ": EOF exception found" )
4792 main.log.error( self.name + ": " + self.handle.before )
4793 main.cleanup()
4794 main.exit()
4795 except Exception:
4796 main.log.exception( self.name + ": Uncaught exception!" )
4797 main.cleanup()
4798 main.exit()
4799
Flavio Castro82ee2f62016-06-07 15:04:12 -07004800 def portstate(self, dpid='of:0000000000000102', port='2', state='enable'):
4801 '''
4802 Description:
4803 Changes the state of port in an OF switch by means of the
4804 PORTSTATUS OF messages.
4805 params:
4806 dpid - (string) Datapath ID of the device
4807 port - (string) target port in the device
4808 state - (string) target state (enable or disabled)
4809 returns:
4810 main.TRUE if no exceptions were thrown and no Errors are
4811 present in the resoponse. Otherwise, returns main.FALSE
4812 '''
4813 try:
4814 cmd = "portstate {} {} {}".format( dpid, port, state )
4815 response = self.sendline( cmd, showResponse=True )
4816 assert response is not None, "Error in sendline"
4817 assert "Command not found:" not in response, response
4818 if "Error" in response or "Failure" in response:
4819 main.log.error( response )
4820 return main.FALSE
4821 return main.TRUE
4822 except AssertionError:
4823 main.log.exception( "" )
4824 return None
4825 except TypeError:
4826 main.log.exception( self.name + ": Object not as expected" )
4827 return main.FALSE
4828 except pexpect.EOF:
4829 main.log.error( self.name + ": EOF exception found" )
4830 main.log.error( self.name + ": " + self.handle.before )
4831 main.cleanup()
4832 main.exit()
4833 except Exception:
4834 main.log.exception( self.name + ": Uncaught exception!" )
4835 main.cleanup()
4836 main.exit()
4837
4838 def logSet( self, level="INFO", app="org.onosproject" ):
4839 """
4840 Set the logging level to lvl for a specific app
4841 returns main.TRUE on success
4842 returns main.FALSE if Error occurred
4843 if noExit is True, TestON will not exit, but clean up
4844 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4845 Level defaults to INFO
4846 """
4847 try:
4848 self.handle.sendline( "log:set %s %s" %( level, app ) )
4849 self.handle.expect( "onos>" )
4850
4851 response = self.handle.before
4852 if re.search( "Error", response ):
4853 return main.FALSE
4854 return main.TRUE
4855 except pexpect.TIMEOUT:
4856 main.log.exception( self.name + ": TIMEOUT exception found" )
4857 main.cleanup()
4858 main.exit()
4859 except pexpect.EOF:
4860 main.log.error( self.name + ": EOF exception found" )
4861 main.log.error( self.name + ": " + self.handle.before )
4862 main.cleanup()
4863 main.exit()
4864 except Exception:
4865 main.log.exception( self.name + ": Uncaught exception!" )
4866 main.cleanup()
4867 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004868
4869 def getGraphDict( self, timeout=60, includeHost=False ):
4870 """
4871 Return a dictionary which describes the latest network topology data as a
4872 graph.
4873 An example of the dictionary:
4874 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4875 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4876 Each vertex should at least have an 'edges' attribute which describes the
4877 adjacency information. The value of 'edges' attribute is also represented by
4878 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4879 list of attributes.
4880 An example of the edges dictionary:
4881 'edges': { vertex2: { 'port': ..., 'weight': ... },
4882 vertex3: { 'port': ..., 'weight': ... } }
4883 If includeHost == True, all hosts (and host-switch links) will be included
4884 in topology data.
4885 """
4886 graphDict = {}
4887 try:
4888 links = self.links()
4889 links = json.loads( links )
4890 devices = self.devices()
4891 devices = json.loads( devices )
4892 idToDevice = {}
4893 for device in devices:
4894 idToDevice[ device[ 'id' ] ] = device
4895 if includeHost:
4896 hosts = self.hosts()
4897 # FIXME: support 'includeHost' argument
4898 for link in links:
4899 nodeA = link[ 'src' ][ 'device' ]
4900 nodeB = link[ 'dst' ][ 'device' ]
4901 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
4902 if not nodeA in graphDict.keys():
4903 graphDict[ nodeA ] = { 'edges':{},
4904 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
4905 'type':idToDevice[ nodeA ][ 'type' ],
4906 'available':idToDevice[ nodeA ][ 'available' ],
4907 'role':idToDevice[ nodeA ][ 'role' ],
4908 'mfr':idToDevice[ nodeA ][ 'mfr' ],
4909 'hw':idToDevice[ nodeA ][ 'hw' ],
4910 'sw':idToDevice[ nodeA ][ 'sw' ],
4911 'serial':idToDevice[ nodeA ][ 'serial' ],
4912 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
4913 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
4914 else:
4915 # Assert nodeB is not connected to any current links of nodeA
4916 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
4917 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
4918 'type':link[ 'type' ],
4919 'state':link[ 'state' ] }
4920 return graphDict
4921 except ( TypeError, ValueError ):
4922 main.log.exception( self.name + ": Object not as expected" )
4923 return None
4924 except KeyError:
4925 main.log.exception( self.name + ": KeyError exception found" )
4926 return None
4927 except AssertionError:
4928 main.log.exception( self.name + ": AssertionError exception found" )
4929 return None
4930 except pexpect.EOF:
4931 main.log.error( self.name + ": EOF exception found" )
4932 main.log.error( self.name + ": " + self.handle.before )
4933 return None
4934 except Exception:
4935 main.log.exception( self.name + ": Uncaught exception!" )
4936 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004937
4938 def getIntentPerfSummary( self ):
4939 '''
4940 Send command to check intent-perf summary
4941 Returns: dictionary for intent-perf summary
4942 if something wrong, function will return None
4943 '''
4944 cmd = "intent-perf -s"
4945 respDic = {}
4946 resp = self.sendline( cmd )
4947 try:
4948 # Generate the dictionary to return
4949 for l in resp.split( "\n" ):
4950 # Delete any white space in line
4951 temp = re.sub( r'\s+', '', l )
4952 temp = temp.split( ":" )
4953 respDic[ temp[0] ] = temp[ 1 ]
4954
4955 except (TypeError, ValueError):
4956 main.log.exception( self.name + ": Object not as expected" )
4957 return None
4958 except KeyError:
4959 main.log.exception( self.name + ": KeyError exception found" )
4960 return None
4961 except AssertionError:
4962 main.log.exception( self.name + ": AssertionError exception found" )
4963 return None
4964 except pexpect.EOF:
4965 main.log.error( self.name + ": EOF exception found" )
4966 main.log.error( self.name + ": " + self.handle.before )
4967 return None
4968 except Exception:
4969 main.log.exception( self.name + ": Uncaught exception!" )
4970 return None
4971 return respDic
4972
4973