blob: 93152ea507a7f298e805c9e92ee667a4677ee4f1 [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="",
Chiyu Chengef109502016-11-21 15:51:38 -0800235 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
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:
Jon Hall67253832016-12-05 09:47:13 -0800252 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800253 self.handle.sendline( "" )
254 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500256 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
Jon Hall67253832016-12-05 09:47:13 -0800260 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800261 if waitForStart:
262 # Wait for onos start ( -w ) and enter onos cli
263 startCliCommand = "onos -w "
264 else:
265 startCliCommand = "onos "
266 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800267 i = self.handle.expect( [
268 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700269 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400270
271 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800272 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800273 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800275 "config:property-set -p org.apache.karaf.shell\
276 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800277 karafTimeout )
278 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800279 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800280 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400281 return main.TRUE
282 else:
kelvin8ec71442015-01-15 16:57:00 -0800283 # If failed, send ctrl+c to process and try again
284 main.log.info( "Starting CLI failed. Retrying..." )
285 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
288 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400289 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800290 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800291 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800292 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800293 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 "config:property-set -p org.apache.karaf.shell\
295 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800296 karafTimeout )
297 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800298 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800299 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400300 return main.TRUE
301 else:
kelvin8ec71442015-01-15 16:57:00 -0800302 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800303 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400304 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400305
Jon Halld4d4b372015-01-28 16:02:41 -0800306 except TypeError:
307 main.log.exception( self.name + ": Object not as expected" )
308 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800310 main.log.error( self.name + ": EOF exception found" )
311 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400312 main.cleanup()
313 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800314 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800315 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400316 main.cleanup()
317 main.exit()
318
suibin zhang116647a2016-05-06 16:30:09 -0700319 def startCellCli( self, karafTimeout="",
320 commandlineTimeout=10, onosStartTimeout=60 ):
321 """
322 Start CLI on onos ecll handle.
323
324 karafTimeout is an optional argument. karafTimeout value passed
325 by user would be used to set the current karaf shell idle timeout.
326 Note that when ever this property is modified the shell will exit and
327 the subsequent login would reflect new idle timeout.
328 Below is an example to start a session with 60 seconds idle timeout
329 ( input value is in milliseconds ):
330
331 tValue = "60000"
332
333 Note: karafTimeout is left as str so that this could be read
334 and passed to startOnosCli from PARAMS file as str.
335 """
336
337 try:
338 self.handle.sendline( "" )
339 x = self.handle.expect( [
340 "\$", "onos>" ], commandlineTimeout)
341
342 if x == 1:
343 main.log.info( "ONOS cli is already running" )
344 return main.TRUE
345
346 # Wait for onos start ( -w ) and enter onos cli
347 self.handle.sendline( "/opt/onos/bin/onos" )
348 i = self.handle.expect( [
349 "onos>",
350 pexpect.TIMEOUT ], onosStartTimeout )
351
352 if i == 0:
353 main.log.info( self.name + " CLI Started successfully" )
354 if karafTimeout:
355 self.handle.sendline(
356 "config:property-set -p org.apache.karaf.shell\
357 sshIdleTimeout " +
358 karafTimeout )
359 self.handle.expect( "\$" )
360 self.handle.sendline( "/opt/onos/bin/onos" )
361 self.handle.expect( "onos>" )
362 return main.TRUE
363 else:
364 # If failed, send ctrl+c to process and try again
365 main.log.info( "Starting CLI failed. Retrying..." )
366 self.handle.send( "\x03" )
367 self.handle.sendline( "/opt/onos/bin/onos" )
368 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
369 timeout=30 )
370 if i == 0:
371 main.log.info( self.name + " CLI Started " +
372 "successfully after retry attempt" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
378 self.handle.expect( "\$" )
379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 main.log.error( "Connection to CLI " +
384 self.name + " timeout" )
385 return main.FALSE
386
387 except TypeError:
388 main.log.exception( self.name + ": Object not as expected" )
389 return None
390 except pexpect.EOF:
391 main.log.error( self.name + ": EOF exception found" )
392 main.log.error( self.name + ": " + self.handle.before )
393 main.cleanup()
394 main.exit()
395 except Exception:
396 main.log.exception( self.name + ": Uncaught exception!" )
397 main.cleanup()
398 main.exit()
399
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800400 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800401 """
402 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800403 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800404 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700405 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800406 Available level: DEBUG, TRACE, INFO, WARN, ERROR
407 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800408 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800409 """
410 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800411 lvlStr = ""
412 if level:
413 lvlStr = "--level=" + level
414
kelvin-onlab338f5512015-02-06 10:53:16 -0800415 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700416 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800418
kelvin-onlab9f541032015-02-04 16:19:53 -0800419 response = self.handle.before
420 if re.search( "Error", response ):
421 return main.FALSE
422 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700423 except pexpect.TIMEOUT:
424 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit:
426 main.cleanup()
427 return None
428 else:
429 main.cleanup()
430 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800431 except pexpect.EOF:
432 main.log.error( self.name + ": EOF exception found" )
433 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700434 if noExit:
435 main.cleanup()
436 return None
437 else:
438 main.cleanup()
439 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800440 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800441 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
446 main.cleanup()
447 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400448
YPZhangebf9eb52016-05-12 15:20:24 -0700449 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800450 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800451 Send a completely user specified string to
452 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400453 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800454
YPZhang14a4aa92016-07-15 13:37:15 -0700455 if noExit is True, TestON will not exit, and return None
YPZhangebf9eb52016-05-12 15:20:24 -0700456
andrewonlaba18f6bf2014-10-13 19:31:54 -0400457 Warning: There are no sanity checking to commands
458 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800459
kelvin8ec71442015-01-15 16:57:00 -0800460 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400461 try:
Jon Halla495f562016-05-16 18:03:26 -0700462 # Try to reconnect if disconnected from cli
463 self.handle.sendline( "" )
464 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
465 if i == 1:
466 main.log.error( self.name + ": onos cli session closed. ")
467 if self.onosIp:
468 main.log.warn( "Trying to reconnect " + self.onosIp )
469 reconnectResult = self.startOnosCli( self.onosIp )
470 if reconnectResult:
471 main.log.info( self.name + ": onos cli session reconnected." )
472 else:
473 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700474 if noExit:
475 return None
476 else:
477 main.cleanup()
478 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700479 else:
480 main.cleanup()
481 main.exit()
482 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700483 main.log.warn( "Timeout when testing cli responsiveness" )
484 main.log.debug( self.handle.before )
485 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700486 self.handle.expect( "onos>" )
487
Jon Hall14a03b52016-05-11 12:07:30 -0700488 if debug:
489 # NOTE: This adds and average of .4 seconds per call
490 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
YPZhangebf9eb52016-05-12 15:20:24 -0700491 self.log( logStr,noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800492 self.handle.sendline( cmdStr )
GlennRCed771242016-01-13 17:02:47 -0800493 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800494 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800495 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800496 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
497 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700498 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700499 main.log.debug( self.name + ": Raw output" )
500 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700501
502 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800503 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800504 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700505 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700506 main.log.debug( self.name + ": ansiEscape output" )
507 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700508
kelvin-onlabfb521662015-02-27 09:52:40 -0800509 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800510 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700511 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700512 main.log.debug( self.name + ": Removed extra returns " +
513 "from output" )
514 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515
516 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800517 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700518 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700519 main.log.debug( self.name + ": parsed and stripped output" )
520 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521
Jon Hall63604932015-02-26 17:09:50 -0800522 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700523 output = response.split( cmdStr.strip(), 1 )
524 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700525 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700526 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700527 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800528 output = output[1].strip()
529 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800530 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800531 return output
GlennRCed771242016-01-13 17:02:47 -0800532 except pexpect.TIMEOUT:
533 main.log.error( self.name + ":ONOS timeout" )
534 if debug:
535 main.log.debug( self.handle.before )
536 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700537 except IndexError:
538 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700539 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800541 except TypeError:
542 main.log.exception( self.name + ": Object not as expected" )
543 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800545 main.log.error( self.name + ": EOF exception found" )
546 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700547 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700548 return None
549 else:
550 main.cleanup()
551 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800552 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800553 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700554 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700555 return None
556 else:
557 main.cleanup()
558 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400559
kelvin8ec71442015-01-15 16:57:00 -0800560 # IMPORTANT NOTE:
561 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800562 # the cli command changing 'a:b' with 'aB'.
563 # Ex ) onos:topology > onosTopology
564 # onos:links > onosLinks
565 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800566
kelvin-onlabd3b64892015-01-20 13:26:24 -0800567 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800568 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400569 Adds a new cluster node by ID and address information.
570 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800571 * nodeId
572 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400573 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800574 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800575 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400576 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 cmdStr = "add-node " + str( nodeId ) + " " +\
578 str( ONOSIp ) + " " + str( tcpPort )
579 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700580 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800581 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800582 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800583 main.log.error( "Error in adding node" )
584 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800585 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400586 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800587 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800589 except AssertionError:
590 main.log.exception( "" )
591 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800592 except TypeError:
593 main.log.exception( self.name + ": Object not as expected" )
594 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400595 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800596 main.log.error( self.name + ": EOF exception found" )
597 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400598 main.cleanup()
599 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800600 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800601 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400602 main.cleanup()
603 main.exit()
604
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800606 """
andrewonlab86dc3082014-10-13 18:18:38 -0400607 Removes a cluster by ID
608 Issues command: 'remove-node [<node-id>]'
609 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800610 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800611 """
andrewonlab86dc3082014-10-13 18:18:38 -0400612 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400613
kelvin-onlabd3b64892015-01-20 13:26:24 -0800614 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700615 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700616 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800617 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700618 if re.search( "Error", handle ):
619 main.log.error( "Error in removing node" )
620 main.log.error( handle )
621 return main.FALSE
622 else:
623 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800624 except AssertionError:
625 main.log.exception( "" )
626 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800627 except TypeError:
628 main.log.exception( self.name + ": Object not as expected" )
629 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400633 main.cleanup()
634 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800635 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800636 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400637 main.cleanup()
638 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400639
Jon Hall61282e32015-03-19 11:34:11 -0700640 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800641 """
andrewonlab7c211572014-10-15 16:45:20 -0400642 List the nodes currently visible
643 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700644 Optional argument:
645 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800646 """
andrewonlab7c211572014-10-15 16:45:20 -0400647 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700648 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700649 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700650 cmdStr += " -j"
651 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700652 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800653 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700654 return output
Jon Hallc6793552016-01-19 14:18:37 -0800655 except AssertionError:
656 main.log.exception( "" )
657 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800658 except TypeError:
659 main.log.exception( self.name + ": Object not as expected" )
660 return None
andrewonlab7c211572014-10-15 16:45:20 -0400661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800662 main.log.error( self.name + ": EOF exception found" )
663 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400664 main.cleanup()
665 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800667 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400668 main.cleanup()
669 main.exit()
670
kelvin8ec71442015-01-15 16:57:00 -0800671 def topology( self ):
672 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700673 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700674 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700675 Return:
676 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800677 """
andrewonlab95ce8322014-10-13 14:12:04 -0400678 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700679 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800680 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800681 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800682 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700683 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400684 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800685 except AssertionError:
686 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800687 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800688 except TypeError:
689 main.log.exception( self.name + ": Object not as expected" )
690 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400691 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800692 main.log.error( self.name + ": EOF exception found" )
693 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400694 main.cleanup()
695 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800696 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800697 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400698 main.cleanup()
699 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800700
jenkins7ead5a82015-03-13 10:28:21 -0700701 def deviceRemove( self, deviceId ):
702 """
703 Removes particular device from storage
704
705 TODO: refactor this function
706 """
707 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700708 cmdStr = "device-remove " + str( deviceId )
709 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800710 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800711 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700712 if re.search( "Error", handle ):
713 main.log.error( "Error in removing device" )
714 main.log.error( handle )
715 return main.FALSE
716 else:
717 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800718 except AssertionError:
719 main.log.exception( "" )
720 return None
jenkins7ead5a82015-03-13 10:28:21 -0700721 except TypeError:
722 main.log.exception( self.name + ": Object not as expected" )
723 return None
724 except pexpect.EOF:
725 main.log.error( self.name + ": EOF exception found" )
726 main.log.error( self.name + ": " + self.handle.before )
727 main.cleanup()
728 main.exit()
729 except Exception:
730 main.log.exception( self.name + ": Uncaught exception!" )
731 main.cleanup()
732 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700733
kelvin-onlabd3b64892015-01-20 13:26:24 -0800734 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800735 """
Jon Hall7b02d952014-10-17 20:14:54 -0400736 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400737 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800739 """
andrewonlab86dc3082014-10-13 18:18:38 -0400740 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700741 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700743 cmdStr += " -j"
744 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800745 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800746 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800748 except AssertionError:
749 main.log.exception( "" )
750 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800751 except TypeError:
752 main.log.exception( self.name + ": Object not as expected" )
753 return None
andrewonlab7c211572014-10-15 16:45:20 -0400754 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800755 main.log.error( self.name + ": EOF exception found" )
756 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400757 main.cleanup()
758 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800759 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800760 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400761 main.cleanup()
762 main.exit()
763
kelvin-onlabd3b64892015-01-20 13:26:24 -0800764 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800765 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800766 This balances the devices across all controllers
767 by issuing command: 'onos> onos:balance-masters'
768 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800769 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800770 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800771 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800773 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800774 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 if re.search( "Error", handle ):
776 main.log.error( "Error in balancing masters" )
777 main.log.error( handle )
778 return main.FALSE
779 else:
780 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800781 except AssertionError:
782 main.log.exception( "" )
783 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800784 except TypeError:
785 main.log.exception( self.name + ": Object not as expected" )
786 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800787 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800788 main.log.error( self.name + ": EOF exception found" )
789 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 main.cleanup()
791 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800792 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800793 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800794 main.cleanup()
795 main.exit()
796
Jon Hallc6793552016-01-19 14:18:37 -0800797 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Returns the output of the masters command.
800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
802 """
803 try:
804 cmdStr = "onos:masters"
805 if jsonFormat:
806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800809 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700810 return output
Jon Hallc6793552016-01-19 14:18:37 -0800811 except AssertionError:
812 main.log.exception( "" )
813 return None
acsmars24950022015-07-30 18:00:43 -0700814 except TypeError:
815 main.log.exception( self.name + ": Object not as expected" )
816 return None
817 except pexpect.EOF:
818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
820 main.cleanup()
821 main.exit()
822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
824 main.cleanup()
825 main.exit()
826
Jon Hallc6793552016-01-19 14:18:37 -0800827 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700828 """
829 Uses the master command to check that the devices' leadership
830 is evenly divided
831
832 Dependencies: checkMasters() and summary()
833
Jon Hall6509dbf2016-06-21 17:01:17 -0700834 Returns main.TRUE if the devices are balanced
835 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700836 Exits on Exception
837 Returns None on TypeError
838 """
839 try:
Jon Hallc6793552016-01-19 14:18:37 -0800840 summaryOutput = self.summary()
841 totalDevices = json.loads( summaryOutput )[ "devices" ]
842 except ( TypeError, ValueError ):
843 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
844 return None
845 try:
acsmars24950022015-07-30 18:00:43 -0700846 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800847 mastersOutput = self.checkMasters()
848 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700849 first = masters[ 0 ][ "size" ]
850 for master in masters:
851 totalOwnedDevices += master[ "size" ]
852 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
853 main.log.error( "Mastership not balanced" )
854 main.log.info( "\n" + self.checkMasters( False ) )
855 return main.FALSE
856 main.log.info( "Mastership balanced between " \
857 + str( len(masters) ) + " masters" )
858 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800859 except ( TypeError, ValueError ):
860 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700861 return None
862 except pexpect.EOF:
863 main.log.error( self.name + ": EOF exception found" )
864 main.log.error( self.name + ": " + self.handle.before )
865 main.cleanup()
866 main.exit()
867 except Exception:
868 main.log.exception( self.name + ": Uncaught exception!" )
869 main.cleanup()
870 main.exit()
871
YPZhangfebf7302016-05-24 16:45:56 -0700872 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800873 """
Jon Halle8217482014-10-17 13:49:14 -0400874 Lists all core links
875 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800877 """
Jon Halle8217482014-10-17 13:49:14 -0400878 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700879 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700882 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800883 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800884 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700885 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800886 except AssertionError:
887 main.log.exception( "" )
888 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800889 except TypeError:
890 main.log.exception( self.name + ": Object not as expected" )
891 return None
Jon Halle8217482014-10-17 13:49:14 -0400892 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800893 main.log.error( self.name + ": EOF exception found" )
894 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400895 main.cleanup()
896 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800898 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400899 main.cleanup()
900 main.exit()
901
kelvin-onlabd3b64892015-01-20 13:26:24 -0800902 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800903 """
Jon Halle8217482014-10-17 13:49:14 -0400904 Lists all ports
905 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800906 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800907 """
Jon Halle8217482014-10-17 13:49:14 -0400908 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800910 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700911 cmdStr += " -j"
912 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800913 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800914 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800916 except AssertionError:
917 main.log.exception( "" )
918 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800919 except TypeError:
920 main.log.exception( self.name + ": Object not as expected" )
921 return None
Jon Halle8217482014-10-17 13:49:14 -0400922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400925 main.cleanup()
926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800928 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400929 main.cleanup()
930 main.exit()
931
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800933 """
Jon Hall983a1702014-10-28 18:44:22 -0400934 Lists all devices and the controllers with roles assigned to them
935 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800936 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800937 """
andrewonlab7c211572014-10-15 16:45:20 -0400938 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700939 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800940 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700941 cmdStr += " -j"
942 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800943 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800944 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700945 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800946 except AssertionError:
947 main.log.exception( "" )
948 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800949 except TypeError:
950 main.log.exception( self.name + ": Object not as expected" )
951 return None
Jon Hall983a1702014-10-28 18:44:22 -0400952 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800953 main.log.error( self.name + ": EOF exception found" )
954 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400955 main.cleanup()
956 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800957 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800958 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400959 main.cleanup()
960 main.exit()
961
kelvin-onlabd3b64892015-01-20 13:26:24 -0800962 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800963 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800964 Given the a string containing the json representation of the "roles"
965 cli command and a partial or whole device id, returns a json object
966 containing the roles output for the first device whose id contains
967 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400968
969 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800970 A dict of the role assignments for the given device or
971 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800972 """
Jon Hall983a1702014-10-28 18:44:22 -0400973 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400975 return None
976 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 rawRoles = self.roles()
978 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800979 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800981 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400983 return device
984 return None
Jon Hallc6793552016-01-19 14:18:37 -0800985 except ( TypeError, ValueError ):
986 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800987 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400988 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800989 main.log.error( self.name + ": EOF exception found" )
990 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400991 main.cleanup()
992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800994 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400995 main.cleanup()
996 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -0800997
kelvin-onlabd3b64892015-01-20 13:26:24 -0800998 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800999 """
Jon Hall94fd0472014-12-08 11:52:42 -08001000 Iterates through each device and checks if there is a master assigned
1001 Returns: main.TRUE if each device has a master
1002 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001003 """
Jon Hall94fd0472014-12-08 11:52:42 -08001004 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 rawRoles = self.roles()
1006 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001007 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001009 # print device
1010 if device[ 'master' ] == "none":
1011 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001012 return main.FALSE
1013 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001014 except ( TypeError, ValueError ):
1015 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001016 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001017 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001020 main.cleanup()
1021 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001022 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001023 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001024 main.cleanup()
1025 main.exit()
1026
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001028 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001029 Returns string of paths, and the cost.
1030 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001031 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001032 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1034 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001035 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001036 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001037 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( "Error in getting paths" )
1039 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001040 else:
kelvin8ec71442015-01-15 16:57:00 -08001041 path = handle.split( ";" )[ 0 ]
1042 cost = handle.split( ";" )[ 1 ]
1043 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001044 except AssertionError:
1045 main.log.exception( "" )
1046 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001047 except TypeError:
1048 main.log.exception( self.name + ": Object not as expected" )
1049 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001050 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001051 main.log.error( self.name + ": EOF exception found" )
1052 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001053 main.cleanup()
1054 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001056 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 main.cleanup()
1058 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001059
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001061 """
Jon Hallffb386d2014-11-21 13:43:38 -08001062 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001063 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001065 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001066 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001067 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001068 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001069 cmdStr += " -j"
1070 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001071 if handle:
1072 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001073 # TODO: Maybe make this less hardcoded
1074 # ConsistentMap Exceptions
1075 assert "org.onosproject.store.service" not in handle
1076 # Node not leader
1077 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001078 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001079 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001080 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001081 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001082 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001083 except TypeError:
1084 main.log.exception( self.name + ": Object not as expected" )
1085 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001087 main.log.error( self.name + ": EOF exception found" )
1088 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 main.cleanup()
1090 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001091 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001092 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001093 main.cleanup()
1094 main.exit()
1095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001097 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001098 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001099
Jon Hallefbd9792015-03-05 16:11:36 -08001100 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001101 partial mac address
1102
Jon Hall42db6dc2014-10-24 19:03:48 -04001103 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001104 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 try:
kelvin8ec71442015-01-15 16:57:00 -08001106 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001107 return None
1108 else:
1109 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001110 rawHosts = self.hosts()
1111 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001112 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001114 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001115 if not host:
1116 pass
1117 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001118 return host
1119 return None
Jon Hallc6793552016-01-19 14:18:37 -08001120 except ( TypeError, ValueError ):
1121 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001122 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001124 main.log.error( self.name + ": EOF exception found" )
1125 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001126 main.cleanup()
1127 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001128 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001129 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001130 main.cleanup()
1131 main.exit()
1132
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001134 """
1135 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001136 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001137
andrewonlab3f0a4af2014-10-17 12:25:14 -04001138 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140 IMPORTANT:
1141 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001142 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001143 Furthermore, it assumes that value of VLAN is '-1'
1144 Description:
kelvin8ec71442015-01-15 16:57:00 -08001145 Converts mininet hosts ( h1, h2, h3... ) into
1146 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1147 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001148 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001152 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 hostHex = hex( int( host ) ).zfill( 12 )
1154 hostHex = str( hostHex ).replace( 'x', '0' )
1155 i = iter( str( hostHex ) )
1156 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1157 hostHex = hostHex + "/-1"
1158 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001159
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001161
Jon Halld4d4b372015-01-28 16:02:41 -08001162 except TypeError:
1163 main.log.exception( self.name + ": Object not as expected" )
1164 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001166 main.log.error( self.name + ": EOF exception found" )
1167 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001168 main.cleanup()
1169 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001170 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001171 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001172 main.cleanup()
1173 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001174
Jeremy Songsterc032f162016-08-04 17:14:49 -07001175 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001176 """
andrewonlabe6745342014-10-17 14:29:13 -04001177 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 * hostIdOne: ONOS host id for host1
1179 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001180 Optional:
1181 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001182 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001183 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001184 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001185 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001186 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001187 Returns:
1188 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001189 """
andrewonlabe6745342014-10-17 14:29:13 -04001190 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001191 cmdStr = "add-host-intent "
1192 if vlanId:
1193 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001194 if setVlan:
1195 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001196 if encap:
1197 cmdStr += "--encapsulation " + str( encap ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001198 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001200 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001201 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001202 if re.search( "Error", handle ):
1203 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001204 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001205 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001206 else:
1207 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001208 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1209 match = re.search('id=0x([\da-f]+),', handle)
1210 if match:
1211 return match.group()[3:-1]
1212 else:
1213 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001214 main.log.debug( "Response from ONOS was: " +
1215 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001216 return None
Jon Hallc6793552016-01-19 14:18:37 -08001217 except AssertionError:
1218 main.log.exception( "" )
1219 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001220 except TypeError:
1221 main.log.exception( self.name + ": Object not as expected" )
1222 return None
andrewonlabe6745342014-10-17 14:29:13 -04001223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001224 main.log.error( self.name + ": EOF exception found" )
1225 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001226 main.cleanup()
1227 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001229 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001230 main.cleanup()
1231 main.exit()
1232
kelvin-onlabd3b64892015-01-20 13:26:24 -08001233 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001234 """
andrewonlab7b31d232014-10-24 13:31:47 -04001235 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 * ingressDevice: device id of ingress device
1237 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001238 Optional:
1239 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 Description:
1241 Adds an optical intent by specifying an ingress and egress device
1242 Returns:
1243 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001244 """
andrewonlab7b31d232014-10-24 13:31:47 -04001245 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001246 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1247 " " + str( egressDevice )
1248 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001249 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001250 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001251 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001252 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001253 main.log.error( "Error in adding Optical intent" )
1254 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001255 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001256 main.log.info( "Optical intent installed between " +
1257 str( ingressDevice ) + " and " +
1258 str( egressDevice ) )
1259 match = re.search('id=0x([\da-f]+),', handle)
1260 if match:
1261 return match.group()[3:-1]
1262 else:
1263 main.log.error( "Error, intent ID not found" )
1264 return None
Jon Hallc6793552016-01-19 14:18:37 -08001265 except AssertionError:
1266 main.log.exception( "" )
1267 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001268 except TypeError:
1269 main.log.exception( self.name + ": Object not as expected" )
1270 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001271 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001272 main.log.error( self.name + ": EOF exception found" )
1273 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001274 main.cleanup()
1275 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001276 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001277 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001278 main.cleanup()
1279 main.exit()
1280
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001282 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001283 ingressDevice,
1284 egressDevice,
1285 portIngress="",
1286 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001287 ethType="",
1288 ethSrc="",
1289 ethDst="",
1290 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001292 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001293 ipProto="",
1294 ipSrc="",
1295 ipDst="",
1296 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001297 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001298 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001299 setVlan="",
1300 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001301 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001302 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001303 * ingressDevice: device id of ingress device
1304 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001305 Optional:
1306 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001307 * ethSrc: specify ethSrc ( i.e. src mac addr )
1308 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001309 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001310 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001311 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001312 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001313 * ipSrc: specify ip source address
1314 * ipDst: specify ip destination address
1315 * tcpSrc: specify tcp source port
1316 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001317 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001318 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001319 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001320 Description:
kelvin8ec71442015-01-15 16:57:00 -08001321 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001322 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001323 Returns:
1324 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001325
Jon Halle3f39ff2015-01-13 11:50:53 -08001326 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001327 options developers provide for point-to-point
1328 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001329 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001330 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001331 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001332
Jeremy Songsterff553672016-05-12 17:06:23 -07001333 if ethType:
1334 cmd += " --ethType " + str( ethType )
1335 if ethSrc:
1336 cmd += " --ethSrc " + str( ethSrc )
1337 if ethDst:
1338 cmd += " --ethDst " + str( ethDst )
1339 if bandwidth:
1340 cmd += " --bandwidth " + str( bandwidth )
1341 if lambdaAlloc:
1342 cmd += " --lambda "
1343 if ipProto:
1344 cmd += " --ipProto " + str( ipProto )
1345 if ipSrc:
1346 cmd += " --ipSrc " + str( ipSrc )
1347 if ipDst:
1348 cmd += " --ipDst " + str( ipDst )
1349 if tcpSrc:
1350 cmd += " --tcpSrc " + str( tcpSrc )
1351 if tcpDst:
1352 cmd += " --tcpDst " + str( tcpDst )
1353 if vlanId:
1354 cmd += " -v " + str( vlanId )
1355 if setVlan:
1356 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001357 if encap:
1358 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001359 if protected:
1360 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001361
kelvin8ec71442015-01-15 16:57:00 -08001362 # Check whether the user appended the port
1363 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001364 if "/" in ingressDevice:
1365 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001366 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001369 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001370 # Would it make sense to throw an exception and exit
1371 # the test?
1372 return None
andrewonlab36af3822014-11-18 17:48:18 -05001373
kelvin8ec71442015-01-15 16:57:00 -08001374 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 str( ingressDevice ) + "/" +\
1376 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001377
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 if "/" in egressDevice:
1379 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001380 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001382 main.log.error( "You must specify the egress port" )
1383 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001384
kelvin8ec71442015-01-15 16:57:00 -08001385 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 str( egressDevice ) + "/" +\
1387 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001388
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001390 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001391 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001392 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001393 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001395 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001397 # TODO: print out all the options in this message?
1398 main.log.info( "Point-to-point intent installed between " +
1399 str( ingressDevice ) + " and " +
1400 str( egressDevice ) )
1401 match = re.search('id=0x([\da-f]+),', handle)
1402 if match:
1403 return match.group()[3:-1]
1404 else:
1405 main.log.error( "Error, intent ID not found" )
1406 return None
Jon Hallc6793552016-01-19 14:18:37 -08001407 except AssertionError:
1408 main.log.exception( "" )
1409 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001410 except TypeError:
1411 main.log.exception( self.name + ": Object not as expected" )
1412 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001413 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001414 main.log.error( self.name + ": EOF exception found" )
1415 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001416 main.cleanup()
1417 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001418 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001419 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001420 main.cleanup()
1421 main.exit()
1422
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001424 self,
shahshreyac2f97072015-03-19 17:04:29 -07001425 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001427 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001429 ethType="",
1430 ethSrc="",
1431 ethDst="",
1432 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001434 ipProto="",
1435 ipSrc="",
1436 ipDst="",
1437 tcpSrc="",
1438 tcpDst="",
1439 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001440 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001441 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001442 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001443 partial=False,
1444 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001445 """
shahshreyad0c80432014-12-04 16:56:05 -08001446 Note:
shahshreya70622b12015-03-19 17:19:00 -07001447 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001448 is same. That is, all ingress devices include port numbers
1449 with a "/" or all ingress devices could specify device
1450 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001451 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001452 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001453 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001455 Optional:
1456 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001457 * ethSrc: specify ethSrc ( i.e. src mac addr )
1458 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001459 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001461 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001462 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001463 * ipSrc: specify ip source address
1464 * ipDst: specify ip destination address
1465 * tcpSrc: specify tcp source port
1466 * tcpDst: specify tcp destination port
1467 * setEthSrc: action to Rewrite Source MAC Address
1468 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001469 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001470 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001471 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001472 Description:
kelvin8ec71442015-01-15 16:57:00 -08001473 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001474 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001475 Returns:
1476 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001477
Jon Halle3f39ff2015-01-13 11:50:53 -08001478 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001479 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001480 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001481 """
shahshreyad0c80432014-12-04 16:56:05 -08001482 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001483 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001484
Jeremy Songsterff553672016-05-12 17:06:23 -07001485 if ethType:
1486 cmd += " --ethType " + str( ethType )
1487 if ethSrc:
1488 cmd += " --ethSrc " + str( ethSrc )
1489 if ethDst:
1490 cmd += " --ethDst " + str( ethDst )
1491 if bandwidth:
1492 cmd += " --bandwidth " + str( bandwidth )
1493 if lambdaAlloc:
1494 cmd += " --lambda "
1495 if ipProto:
1496 cmd += " --ipProto " + str( ipProto )
1497 if ipSrc:
1498 cmd += " --ipSrc " + str( ipSrc )
1499 if ipDst:
1500 cmd += " --ipDst " + str( ipDst )
1501 if tcpSrc:
1502 cmd += " --tcpSrc " + str( tcpSrc )
1503 if tcpDst:
1504 cmd += " --tcpDst " + str( tcpDst )
1505 if setEthSrc:
1506 cmd += " --setEthSrc " + str( setEthSrc )
1507 if setEthDst:
1508 cmd += " --setEthDst " + str( setEthDst )
1509 if vlanId:
1510 cmd += " -v " + str( vlanId )
1511 if setVlan:
1512 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001513 if partial:
1514 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001515 if encap:
1516 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001517
kelvin8ec71442015-01-15 16:57:00 -08001518 # Check whether the user appended the port
1519 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001520
1521 if portIngressList is None:
1522 for ingressDevice in ingressDeviceList:
1523 if "/" in ingressDevice:
1524 cmd += " " + str( ingressDevice )
1525 else:
1526 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001527 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001528 # TODO: perhaps more meaningful return
1529 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001530 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001531 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001532 for ingressDevice, portIngress in zip( ingressDeviceList,
1533 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001534 cmd += " " + \
1535 str( ingressDevice ) + "/" +\
1536 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001537 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001538 main.log.error( "Device list and port list does not " +
1539 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001540 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 if "/" in egressDevice:
1542 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001543 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001545 main.log.error( "You must specify " +
1546 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001547 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001548
kelvin8ec71442015-01-15 16:57:00 -08001549 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 str( egressDevice ) + "/" +\
1551 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001553 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001554 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001555 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001556 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001557 main.log.error( "Error in adding multipoint-to-singlepoint " +
1558 "intent" )
1559 return None
shahshreyad0c80432014-12-04 16:56:05 -08001560 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001561 match = re.search('id=0x([\da-f]+),', handle)
1562 if match:
1563 return match.group()[3:-1]
1564 else:
1565 main.log.error( "Error, intent ID not found" )
1566 return None
Jon Hallc6793552016-01-19 14:18:37 -08001567 except AssertionError:
1568 main.log.exception( "" )
1569 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001570 except TypeError:
1571 main.log.exception( self.name + ": Object not as expected" )
1572 return None
1573 except pexpect.EOF:
1574 main.log.error( self.name + ": EOF exception found" )
1575 main.log.error( self.name + ": " + self.handle.before )
1576 main.cleanup()
1577 main.exit()
1578 except Exception:
1579 main.log.exception( self.name + ": Uncaught exception!" )
1580 main.cleanup()
1581 main.exit()
1582
1583 def addSinglepointToMultipointIntent(
1584 self,
1585 ingressDevice,
1586 egressDeviceList,
1587 portIngress="",
1588 portEgressList=None,
1589 ethType="",
1590 ethSrc="",
1591 ethDst="",
1592 bandwidth="",
1593 lambdaAlloc=False,
1594 ipProto="",
1595 ipSrc="",
1596 ipDst="",
1597 tcpSrc="",
1598 tcpDst="",
1599 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001600 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001602 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001603 partial=False,
1604 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001605 """
1606 Note:
1607 This function assumes the format of all egress devices
1608 is same. That is, all egress devices include port numbers
1609 with a "/" or all egress devices could specify device
1610 ids and port numbers seperately.
1611 Required:
1612 * EgressDeviceList: List of device ids of egress device
1613 ( Atleast 2 eress devices required in the list )
1614 * ingressDevice: device id of ingress device
1615 Optional:
1616 * ethType: specify ethType
1617 * ethSrc: specify ethSrc ( i.e. src mac addr )
1618 * ethDst: specify ethDst ( i.e. dst mac addr )
1619 * bandwidth: specify bandwidth capacity of link
1620 * lambdaAlloc: if True, intent will allocate lambda
1621 for the specified intent
1622 * ipProto: specify ip protocol
1623 * ipSrc: specify ip source address
1624 * ipDst: specify ip destination address
1625 * tcpSrc: specify tcp source port
1626 * tcpDst: specify tcp destination port
1627 * setEthSrc: action to Rewrite Source MAC Address
1628 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001629 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001630 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001631 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001632 Description:
1633 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1634 specifying device id's and optional fields
1635 Returns:
1636 A string of the intent id or None on error
1637
1638 NOTE: This function may change depending on the
1639 options developers provide for singlepoint-to-multipoint
1640 intent via cli
1641 """
1642 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001643 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001644
Jeremy Songsterff553672016-05-12 17:06:23 -07001645 if ethType:
1646 cmd += " --ethType " + str( ethType )
1647 if ethSrc:
1648 cmd += " --ethSrc " + str( ethSrc )
1649 if ethDst:
1650 cmd += " --ethDst " + str( ethDst )
1651 if bandwidth:
1652 cmd += " --bandwidth " + str( bandwidth )
1653 if lambdaAlloc:
1654 cmd += " --lambda "
1655 if ipProto:
1656 cmd += " --ipProto " + str( ipProto )
1657 if ipSrc:
1658 cmd += " --ipSrc " + str( ipSrc )
1659 if ipDst:
1660 cmd += " --ipDst " + str( ipDst )
1661 if tcpSrc:
1662 cmd += " --tcpSrc " + str( tcpSrc )
1663 if tcpDst:
1664 cmd += " --tcpDst " + str( tcpDst )
1665 if setEthSrc:
1666 cmd += " --setEthSrc " + str( setEthSrc )
1667 if setEthDst:
1668 cmd += " --setEthDst " + str( setEthDst )
1669 if vlanId:
1670 cmd += " -v " + str( vlanId )
1671 if setVlan:
1672 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001673 if partial:
1674 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001675 if encap:
1676 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001677
1678 # Check whether the user appended the port
1679 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001680
kelvin-onlabb9408212015-04-01 13:34:04 -07001681 if "/" in ingressDevice:
1682 cmd += " " + str( ingressDevice )
1683 else:
1684 if not portIngress:
1685 main.log.error( "You must specify " +
1686 "the Ingress port" )
1687 return main.FALSE
1688
1689 cmd += " " +\
1690 str( ingressDevice ) + "/" +\
1691 str( portIngress )
1692
1693 if portEgressList is None:
1694 for egressDevice in egressDeviceList:
1695 if "/" in egressDevice:
1696 cmd += " " + str( egressDevice )
1697 else:
1698 main.log.error( "You must specify " +
1699 "the egress port" )
1700 # TODO: perhaps more meaningful return
1701 return main.FALSE
1702 else:
1703 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001704 for egressDevice, portEgress in zip( egressDeviceList,
1705 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001706 cmd += " " + \
1707 str( egressDevice ) + "/" +\
1708 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001709 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001710 main.log.error( "Device list and port list does not " +
1711 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001712 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001713 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001714 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001715 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001716 # If error, return error message
1717 if re.search( "Error", handle ):
1718 main.log.error( "Error in adding singlepoint-to-multipoint " +
1719 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001720 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001721 else:
1722 match = re.search('id=0x([\da-f]+),', handle)
1723 if match:
1724 return match.group()[3:-1]
1725 else:
1726 main.log.error( "Error, intent ID not found" )
1727 return None
Jon Hallc6793552016-01-19 14:18:37 -08001728 except AssertionError:
1729 main.log.exception( "" )
1730 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001731 except TypeError:
1732 main.log.exception( self.name + ": Object not as expected" )
1733 return None
shahshreyad0c80432014-12-04 16:56:05 -08001734 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001735 main.log.error( self.name + ": EOF exception found" )
1736 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001737 main.cleanup()
1738 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001739 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001740 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001741 main.cleanup()
1742 main.exit()
1743
Hari Krishna9e232602015-04-13 17:29:08 -07001744 def addMplsIntent(
1745 self,
1746 ingressDevice,
1747 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001748 ingressPort="",
1749 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001750 ethType="",
1751 ethSrc="",
1752 ethDst="",
1753 bandwidth="",
1754 lambdaAlloc=False,
1755 ipProto="",
1756 ipSrc="",
1757 ipDst="",
1758 tcpSrc="",
1759 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001760 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001761 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001762 priority=""):
1763 """
1764 Required:
1765 * ingressDevice: device id of ingress device
1766 * egressDevice: device id of egress device
1767 Optional:
1768 * ethType: specify ethType
1769 * ethSrc: specify ethSrc ( i.e. src mac addr )
1770 * ethDst: specify ethDst ( i.e. dst mac addr )
1771 * bandwidth: specify bandwidth capacity of link
1772 * lambdaAlloc: if True, intent will allocate lambda
1773 for the specified intent
1774 * ipProto: specify ip protocol
1775 * ipSrc: specify ip source address
1776 * ipDst: specify ip destination address
1777 * tcpSrc: specify tcp source port
1778 * tcpDst: specify tcp destination port
1779 * ingressLabel: Ingress MPLS label
1780 * egressLabel: Egress MPLS label
1781 Description:
1782 Adds MPLS intent by
1783 specifying device id's and optional fields
1784 Returns:
1785 A string of the intent id or None on error
1786
1787 NOTE: This function may change depending on the
1788 options developers provide for MPLS
1789 intent via cli
1790 """
1791 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001792 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001793
Jeremy Songsterff553672016-05-12 17:06:23 -07001794 if ethType:
1795 cmd += " --ethType " + str( ethType )
1796 if ethSrc:
1797 cmd += " --ethSrc " + str( ethSrc )
1798 if ethDst:
1799 cmd += " --ethDst " + str( ethDst )
1800 if bandwidth:
1801 cmd += " --bandwidth " + str( bandwidth )
1802 if lambdaAlloc:
1803 cmd += " --lambda "
1804 if ipProto:
1805 cmd += " --ipProto " + str( ipProto )
1806 if ipSrc:
1807 cmd += " --ipSrc " + str( ipSrc )
1808 if ipDst:
1809 cmd += " --ipDst " + str( ipDst )
1810 if tcpSrc:
1811 cmd += " --tcpSrc " + str( tcpSrc )
1812 if tcpDst:
1813 cmd += " --tcpDst " + str( tcpDst )
1814 if ingressLabel:
1815 cmd += " --ingressLabel " + str( ingressLabel )
1816 if egressLabel:
1817 cmd += " --egressLabel " + str( egressLabel )
1818 if priority:
1819 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001820
1821 # Check whether the user appended the port
1822 # or provided it as an input
1823 if "/" in ingressDevice:
1824 cmd += " " + str( ingressDevice )
1825 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001826 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001827 main.log.error( "You must specify the ingress port" )
1828 return None
1829
1830 cmd += " " + \
1831 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001832 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001833
1834 if "/" in egressDevice:
1835 cmd += " " + str( egressDevice )
1836 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001837 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001838 main.log.error( "You must specify the egress port" )
1839 return None
1840
1841 cmd += " " +\
1842 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001843 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001844
1845 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001846 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001847 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001848 # If error, return error message
1849 if re.search( "Error", handle ):
1850 main.log.error( "Error in adding mpls intent" )
1851 return None
1852 else:
1853 # TODO: print out all the options in this message?
1854 main.log.info( "MPLS intent installed between " +
1855 str( ingressDevice ) + " and " +
1856 str( egressDevice ) )
1857 match = re.search('id=0x([\da-f]+),', handle)
1858 if match:
1859 return match.group()[3:-1]
1860 else:
1861 main.log.error( "Error, intent ID not found" )
1862 return None
Jon Hallc6793552016-01-19 14:18:37 -08001863 except AssertionError:
1864 main.log.exception( "" )
1865 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001866 except TypeError:
1867 main.log.exception( self.name + ": Object not as expected" )
1868 return None
1869 except pexpect.EOF:
1870 main.log.error( self.name + ": EOF exception found" )
1871 main.log.error( self.name + ": " + self.handle.before )
1872 main.cleanup()
1873 main.exit()
1874 except Exception:
1875 main.log.exception( self.name + ": Uncaught exception!" )
1876 main.cleanup()
1877 main.exit()
1878
Jon Hallefbd9792015-03-05 16:11:36 -08001879 def removeIntent( self, intentId, app='org.onosproject.cli',
1880 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001881 """
shahshreya1c818fc2015-02-26 13:44:08 -08001882 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001883 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001884 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001885 -p or --purge: Purge the intent from the store after removal
1886
Jon Halle3f39ff2015-01-13 11:50:53 -08001887 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001888 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001889 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001890 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001891 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001892 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001893 if purge:
1894 cmdStr += " -p"
1895 if sync:
1896 cmdStr += " -s"
1897
1898 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001899 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001900 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001901 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001902 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001903 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001904 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001905 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001906 # TODO: Should this be main.TRUE
1907 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001908 except AssertionError:
1909 main.log.exception( "" )
1910 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001911 except TypeError:
1912 main.log.exception( self.name + ": Object not as expected" )
1913 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001915 main.log.error( self.name + ": EOF exception found" )
1916 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001917 main.cleanup()
1918 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001920 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001921 main.cleanup()
1922 main.exit()
1923
YPZhangfebf7302016-05-24 16:45:56 -07001924 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001925 """
1926 Description:
1927 Remove all the intents
1928 Optional args:-
1929 -s or --sync: Waits for the removal before returning
1930 -p or --purge: Purge the intent from the store after removal
1931 Returns:
1932 Returns main.TRUE if all intents are removed, otherwise returns
1933 main.FALSE; Returns None for exception
1934 """
1935 try:
1936 cmdStr = "remove-intent"
1937 if purge:
1938 cmdStr += " -p"
1939 if sync:
1940 cmdStr += " -s"
1941
1942 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001943 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001944 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001945 assert "Command not found:" not in handle, handle
1946 if re.search( "Error", handle ):
1947 main.log.error( "Error in removing intent" )
1948 return main.FALSE
1949 else:
1950 return main.TRUE
1951 except AssertionError:
1952 main.log.exception( "" )
1953 return None
1954 except TypeError:
1955 main.log.exception( self.name + ": Object not as expected" )
1956 return None
1957 except pexpect.EOF:
1958 main.log.error( self.name + ": EOF exception found" )
1959 main.log.error( self.name + ": " + self.handle.before )
1960 main.cleanup()
1961 main.exit()
1962 except Exception:
1963 main.log.exception( self.name + ": Uncaught exception!" )
1964 main.cleanup()
1965 main.exit()
1966
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001967 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001968 """
1969 Purges all WITHDRAWN Intents
1970 """
1971 try:
1972 cmdStr = "purge-intents"
1973 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001974 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001975 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001976 if re.search( "Error", handle ):
1977 main.log.error( "Error in purging intents" )
1978 return main.FALSE
1979 else:
1980 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001981 except AssertionError:
1982 main.log.exception( "" )
1983 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001984 except TypeError:
1985 main.log.exception( self.name + ": Object not as expected" )
1986 return None
1987 except pexpect.EOF:
1988 main.log.error( self.name + ": EOF exception found" )
1989 main.log.error( self.name + ": " + self.handle.before )
1990 main.cleanup()
1991 main.exit()
1992 except Exception:
1993 main.log.exception( self.name + ": Uncaught exception!" )
1994 main.cleanup()
1995 main.exit()
1996
kelvin-onlabd3b64892015-01-20 13:26:24 -08001997 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001998 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001999 NOTE: This method should be used after installing application:
2000 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002001 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002002 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002003 Description:
2004 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002005 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002006 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002007 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002009 cmdStr += " -j"
2010 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002011 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002012 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002013 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002014 except AssertionError:
2015 main.log.exception( "" )
2016 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002017 except TypeError:
2018 main.log.exception( self.name + ": Object not as expected" )
2019 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002021 main.log.error( self.name + ": EOF exception found" )
2022 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002023 main.cleanup()
2024 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002026 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002027 main.cleanup()
2028 main.exit()
2029
pingping-lin54b03372015-08-13 14:43:10 -07002030 def ipv4RouteNumber( self ):
2031 """
2032 NOTE: This method should be used after installing application:
2033 onos-app-sdnip
2034 Description:
2035 Obtain the total IPv4 routes number in the system
2036 """
2037 try:
2038 cmdStr = "routes -s -j"
2039 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002040 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002041 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002042 jsonResult = json.loads( handle )
2043 return jsonResult['totalRoutes4']
Jon Hallc6793552016-01-19 14:18:37 -08002044 except AssertionError:
2045 main.log.exception( "" )
2046 return None
2047 except ( TypeError, ValueError ):
2048 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002049 return None
2050 except pexpect.EOF:
2051 main.log.error( self.name + ": EOF exception found" )
2052 main.log.error( self.name + ": " + self.handle.before )
2053 main.cleanup()
2054 main.exit()
2055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
2057 main.cleanup()
2058 main.exit()
2059
pingping-lin8244a3b2015-09-16 13:36:56 -07002060 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002061 """
andrewonlabe6745342014-10-17 14:29:13 -04002062 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002063 Obtain intents from the ONOS cli.
2064 Optional:
2065 * jsonFormat: Enable output formatting in json, default to True
2066 * summary: Whether only output the intent summary, defaults to False
2067 * type: Only output a certain type of intent. This options is valid
2068 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002069 """
andrewonlabe6745342014-10-17 14:29:13 -04002070 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002071 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002072 if summary:
2073 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002075 cmdStr += " -j"
2076 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002077 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002078 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002079 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002080 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002081 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002082 else:
Jon Hallff566d52016-01-15 14:45:36 -08002083 intentType = ""
2084 # IF we want the summary of a specific intent type
2085 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002086 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002087 if intentType in jsonResult.keys():
2088 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002089 else:
Jon Hallff566d52016-01-15 14:45:36 -08002090 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002091 return handle
2092 else:
2093 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002094 except AssertionError:
2095 main.log.exception( "" )
2096 return None
2097 except ( TypeError, ValueError ):
2098 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002099 return None
2100 except pexpect.EOF:
2101 main.log.error( self.name + ": EOF exception found" )
2102 main.log.error( self.name + ": " + self.handle.before )
2103 main.cleanup()
2104 main.exit()
2105 except Exception:
2106 main.log.exception( self.name + ": Uncaught exception!" )
2107 main.cleanup()
2108 main.exit()
2109
kelvin-onlab54400a92015-02-26 18:05:51 -08002110 def getIntentState(self, intentsId, intentsJson=None):
2111 """
You Wangfdcbfc42016-05-16 12:16:53 -07002112 Description:
2113 Gets intent state. Accepts a single intent ID (string type) or a
2114 list of intent IDs.
2115 Parameters:
2116 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002117 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002118 Returns:
2119 Returns the state (string type) of the ID if a single intent ID is
2120 accepted.
2121 Returns a list of dictionaries if a list of intent IDs is accepted,
2122 and each dictionary maps 'id' to the Intent ID and 'state' to
2123 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002124 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002125 try:
2126 state = "State is Undefined"
2127 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002128 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002129 else:
Jon Hallc6793552016-01-19 14:18:37 -08002130 rawJson = intentsJson
2131 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002132 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002133 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002134 if intentsId == intent[ 'id' ]:
2135 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002136 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002137 main.log.info( "Cannot find intent ID" + str( intentsId ) +
2138 " on the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002140 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002141 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002142 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002143 stateDict = {}
Jon Hallc6793552016-01-19 14:18:37 -08002144 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002145 if intentsId[ i ] == intents[ 'id' ]:
2146 stateDict[ 'state' ] = intents[ 'state' ]
2147 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002148 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 break
Jon Hallefbd9792015-03-05 16:11:36 -08002150 if len( intentsId ) != len( dictList ):
2151 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002152 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002153 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002154 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002155 return None
Jon Hallc6793552016-01-19 14:18:37 -08002156 except ( TypeError, ValueError ):
2157 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002158 return None
2159 except pexpect.EOF:
2160 main.log.error( self.name + ": EOF exception found" )
2161 main.log.error( self.name + ": " + self.handle.before )
2162 main.cleanup()
2163 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002164 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002165 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002166 main.cleanup()
2167 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002168
kelvin-onlabf512e942015-06-08 19:42:59 -07002169 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002170 """
2171 Description:
2172 Check intents state
2173 Required:
2174 intentsId - List of intents ID to be checked
2175 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002176 expectedState - Check the expected state(s) of each intents
2177 state in the list.
2178 *NOTE: You can pass in a list of expected state,
2179 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002180 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002181 Returns main.TRUE only if all intent are the same as expected states
2182 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002183 """
2184 try:
2185 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002186 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002187 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002188 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002189 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002190 "getting intents state" )
2191 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002192
2193 if isinstance( expectedState, types.StringType ):
2194 for intents in intentsDict:
2195 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002196 main.log.debug( self.name + " : Intent ID - " +
2197 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002198 " actual state = " +
2199 intents.get( 'state' )
2200 + " does not equal expected state = "
2201 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002202 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002203
2204 elif isinstance( expectedState, types.ListType ):
2205 for intents in intentsDict:
2206 if not any( state == intents.get( 'state' ) for state in
2207 expectedState ):
2208 main.log.debug( self.name + " : Intent ID - " +
2209 intents.get( 'id' ) +
2210 " actual state = " +
2211 intents.get( 'state' ) +
2212 " does not equal expected states = "
2213 + str( expectedState ) )
2214 returnValue = main.FALSE
2215
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002216 if returnValue == main.TRUE:
2217 main.log.info( self.name + ": All " +
2218 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002219 " intents are in " + str( expectedState ) +
2220 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 return returnValue
2222 except TypeError:
2223 main.log.exception( self.name + ": Object not as expected" )
2224 return None
2225 except pexpect.EOF:
2226 main.log.error( self.name + ": EOF exception found" )
2227 main.log.error( self.name + ": " + self.handle.before )
2228 main.cleanup()
2229 main.exit()
2230 except Exception:
2231 main.log.exception( self.name + ": Uncaught exception!" )
2232 main.cleanup()
2233 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002234
You Wang66518af2016-05-16 15:32:59 -07002235 def compareIntent( self, intentDict ):
2236 """
2237 Description:
2238 Compare the intent ids and states provided in the argument with all intents in ONOS
2239 Return:
2240 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2241 Arguments:
2242 intentDict: a dictionary which maps intent ids to intent states
2243 """
2244 try:
2245 intentsRaw = self.intents()
2246 intentsJson = json.loads( intentsRaw )
2247 intentDictONOS = {}
2248 for intent in intentsJson:
2249 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002250 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002251 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002252 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002253 str( len( intentDict ) ) + " expected and " +
2254 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002255 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002256 for intentID in intentDict.keys():
2257 if not intentID in intentDictONOS.keys():
2258 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2259 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002260 else:
2261 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2262 main.log.debug( self.name + ": intent ID - " + intentID +
2263 " expected state is " + intentDict[ intentID ] +
2264 " but actual state is " + intentDictONOS[ intentID ] )
2265 returnValue = main.FALSE
2266 intentDictONOS.pop( intentID )
2267 if len( intentDictONOS ) > 0:
2268 returnValue = main.FALSE
2269 for intentID in intentDictONOS.keys():
2270 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002271 if returnValue == main.TRUE:
2272 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2273 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002274 except KeyError:
2275 main.log.exception( self.name + ": KeyError exception found" )
2276 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002277 except ( TypeError, ValueError ):
2278 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002279 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002280 except pexpect.EOF:
2281 main.log.error( self.name + ": EOF exception found" )
2282 main.log.error( self.name + ": " + self.handle.before )
2283 main.cleanup()
2284 main.exit()
2285 except Exception:
2286 main.log.exception( self.name + ": Uncaught exception!" )
2287 main.cleanup()
2288 main.exit()
2289
YPZhang14a4aa92016-07-15 13:37:15 -07002290 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002291 """
2292 Description:
2293 Check the number of installed intents.
2294 Optional:
2295 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002296 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002297 Return:
2298 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2299 , otherwise, returns main.FALSE.
2300 """
2301
2302 try:
2303 cmd = "intents -s -j"
2304
2305 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002306 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
GlennRCed771242016-01-13 17:02:47 -08002307 if response == None:
YPZhang0584d432016-06-21 15:20:13 -07002308 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002309 response = json.loads( response )
2310
2311 # get total and installed number, see if they are match
2312 allState = response.get( 'all' )
2313 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002314 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002315 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002316 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002317 return main.FALSE
2318
Jon Hallc6793552016-01-19 14:18:37 -08002319 except ( TypeError, ValueError ):
2320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002321 return None
2322 except pexpect.EOF:
2323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002325 if noExit:
2326 return main.FALSE
2327 else:
2328 main.cleanup()
2329 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002330 except Exception:
2331 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002332 if noExit:
2333 return main.FALSE
2334 else:
2335 main.cleanup()
2336 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002337 except pexpect.TIMEOUT:
2338 main.log.error( self.name + ": ONOS timeout" )
2339 return None
GlennRCed771242016-01-13 17:02:47 -08002340
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002341 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002342 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002343 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002344 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002345 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002346 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002347 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002348 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002349 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002350 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002351 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002352 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002353 if noCore:
2354 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002355 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002356 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002357 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002358 assert "Command not found:" not in handle, handle
2359 if re.search( "Error:", handle ):
2360 main.log.error( self.name + ": flows() response: " +
2361 str( handle ) )
2362 return handle
2363 except AssertionError:
2364 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002365 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002366 except TypeError:
2367 main.log.exception( self.name + ": Object not as expected" )
2368 return None
Jon Hallc6793552016-01-19 14:18:37 -08002369 except pexpect.TIMEOUT:
2370 main.log.error( self.name + ": ONOS timeout" )
2371 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002373 main.log.error( self.name + ": EOF exception found" )
2374 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002375 main.cleanup()
2376 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002377 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002378 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002379 main.cleanup()
2380 main.exit()
2381
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002382 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002383 count = self.getTotalFlowsNum( timeout=timeout )
2384 count = int (count) if count else 0
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002385 return count if (count > min) else False
GlennRCed771242016-01-13 17:02:47 -08002386
YPZhangebf9eb52016-05-12 15:20:24 -07002387 def checkFlowsState( self, isPENDING=True, timeout=60,noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002388 """
2389 Description:
GlennRCed771242016-01-13 17:02:47 -08002390 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002391 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2392 if the count of those states is 0, which means all current flows
2393 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002394 Optional:
GlennRCed771242016-01-13 17:02:47 -08002395 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002396 Return:
2397 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002398 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002399 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002400 """
2401 try:
GlennRCed771242016-01-13 17:02:47 -08002402 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2403 checkedStates = []
2404 statesCount = [0, 0, 0, 0]
2405 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002406 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002407 if rawFlows:
2408 # if we didn't get flows or flows function return None, we should return
2409 # main.Flase
2410 checkedStates.append( json.loads( rawFlows ) )
2411 else:
2412 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002413 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002414 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002415 try:
2416 statesCount[i] += int( c.get( "flowCount" ) )
2417 except TypeError:
2418 main.log.exception( "Json object not as expected" )
2419 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002420
GlennRCed771242016-01-13 17:02:47 -08002421 # We want to count PENDING_ADD if isPENDING is true
2422 if isPENDING:
2423 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2424 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002425 else:
GlennRCed771242016-01-13 17:02:47 -08002426 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2427 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002428 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002429 except ( TypeError, ValueError ):
2430 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002431 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002432
YPZhang240842b2016-05-17 12:00:50 -07002433 except AssertionError:
2434 main.log.exception( "" )
2435 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002436 except pexpect.EOF:
2437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + ": " + self.handle.before )
2439 main.cleanup()
2440 main.exit()
2441 except Exception:
2442 main.log.exception( self.name + ": Uncaught exception!" )
2443 main.cleanup()
2444 main.exit()
YPZhangebf9eb52016-05-12 15:20:24 -07002445 except pexpect.TIMEOUT:
2446 main.log.error( self.name + ": ONOS timeout" )
2447 return None
2448
kelvin-onlab4df89f22015-04-13 18:10:23 -07002449
GlennRCed771242016-01-13 17:02:47 -08002450 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002451 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002452 """
andrewonlab87852b02014-11-19 18:44:19 -05002453 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002454 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002455 a specific point-to-point intent definition
2456 Required:
GlennRCed771242016-01-13 17:02:47 -08002457 * ingress: specify source dpid
2458 * egress: specify destination dpid
2459 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002460 Optional:
GlennRCed771242016-01-13 17:02:47 -08002461 * offset: the keyOffset is where the next batch of intents
2462 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002463 * noExit: If set to True, TestON will not exit if any error when issus command
2464 * getResponse: If set to True, function will return ONOS response.
2465
GlennRCed771242016-01-13 17:02:47 -08002466 Returns: If failed to push test intents, it will returen None,
2467 if successful, return true.
2468 Timeout expection will return None,
2469 TypeError will return false
2470 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002471 """
andrewonlab87852b02014-11-19 18:44:19 -05002472 try:
GlennRCed771242016-01-13 17:02:47 -08002473 if background:
2474 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002475 else:
GlennRCed771242016-01-13 17:02:47 -08002476 back = ""
2477 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002478 ingress,
2479 egress,
2480 batchSize,
2481 offset,
2482 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002483 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002484 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002485 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002486 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002487 if getResponse:
2488 return response
2489
GlennRCed771242016-01-13 17:02:47 -08002490 # TODO: We should handle if there is failure in installation
2491 return main.TRUE
2492
Jon Hallc6793552016-01-19 14:18:37 -08002493 except AssertionError:
2494 main.log.exception( "" )
2495 return None
GlennRCed771242016-01-13 17:02:47 -08002496 except pexpect.TIMEOUT:
2497 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002498 return None
andrewonlab87852b02014-11-19 18:44:19 -05002499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002502 main.cleanup()
2503 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002504 except TypeError:
2505 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002506 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002507 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002508 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002509 main.cleanup()
2510 main.exit()
2511
YPZhangebf9eb52016-05-12 15:20:24 -07002512 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002513 """
2514 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002515 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002516 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002517 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002518 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002519 """
YPZhange3109a72016-02-02 11:25:37 -08002520
YPZhangb5d3f832016-01-23 22:54:26 -08002521 try:
YPZhange3109a72016-02-02 11:25:37 -08002522 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002523 cmd = "flows -c added"
2524 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2525 if rawFlows:
2526 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002527 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002528 for l in rawFlows:
2529 totalFlows += int(l.split("Count=")[1])
2530 else:
2531 main.log.error("Response not as expected!")
2532 return None
2533 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002534
You Wangd3cb2ce2016-05-16 14:01:24 -07002535 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002536 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002537 return None
2538 except pexpect.EOF:
2539 main.log.error( self.name + ": EOF exception found" )
2540 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002541 if not noExit:
2542 main.cleanup()
2543 main.exit()
2544 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002545 except Exception:
2546 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002547 if not noExit:
2548 main.cleanup()
2549 main.exit()
2550 return None
YPZhangebf9eb52016-05-12 15:20:24 -07002551 except pexpect.TIMEOUT:
2552 main.log.error( self.name + ": ONOS timeout" )
2553 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002554
YPZhang14a4aa92016-07-15 13:37:15 -07002555 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002556 """
2557 Description:
2558 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002559 Optional:
2560 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002561 Return:
2562 The number of intents
2563 """
2564 try:
2565 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002566 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
YPZhangb5d3f832016-01-23 22:54:26 -08002567 if response == None:
2568 return -1
2569 response = json.loads( response )
2570 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002571 except ( TypeError, ValueError ):
2572 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002573 return None
2574 except pexpect.EOF:
2575 main.log.error( self.name + ": EOF exception found" )
2576 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002577 if noExit:
2578 return -1
2579 else:
2580 main.cleanup()
2581 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002582 except Exception:
2583 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002584 if noExit:
2585 return -1
2586 else:
2587 main.cleanup()
2588 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002589
kelvin-onlabd3b64892015-01-20 13:26:24 -08002590 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002591 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002592 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002593 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002594 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002595 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002596 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002597 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002598 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002599 cmdStr += " -j"
2600 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002601 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002602 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002603 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002604 except AssertionError:
2605 main.log.exception( "" )
2606 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002607 except TypeError:
2608 main.log.exception( self.name + ": Object not as expected" )
2609 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002611 main.log.error( self.name + ": EOF exception found" )
2612 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002613 main.cleanup()
2614 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002615 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002616 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002617 main.cleanup()
2618 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002619
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002621 """
2622 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002623 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002624 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002625 """
andrewonlab867212a2014-10-22 20:13:38 -04002626 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002627 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002628 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002629 cmdStr += " -j"
2630 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002631 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002632 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002633 if handle:
2634 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002635 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002636 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002637 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002638 else:
2639 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002640 except AssertionError:
2641 main.log.exception( "" )
2642 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002643 except TypeError:
2644 main.log.exception( self.name + ": Object not as expected" )
2645 return None
andrewonlab867212a2014-10-22 20:13:38 -04002646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002649 main.cleanup()
2650 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002651 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002652 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002653 main.cleanup()
2654 main.exit()
2655
kelvin8ec71442015-01-15 16:57:00 -08002656 # Wrapper functions ****************
2657 # Wrapper functions use existing driver
2658 # functions and extends their use case.
2659 # For example, we may use the output of
2660 # a normal driver function, and parse it
2661 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002662
kelvin-onlabd3b64892015-01-20 13:26:24 -08002663 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002664 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002665 Description:
2666 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002667 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002668 try:
kelvin8ec71442015-01-15 16:57:00 -08002669 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002670 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002671 if intentsStr is None:
2672 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002673 # Convert to a dictionary
2674 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002675 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002676 for intent in intents:
2677 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002678 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002679 except TypeError:
2680 main.log.exception( self.name + ": Object not as expected" )
2681 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002682 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002683 main.log.error( self.name + ": EOF exception found" )
2684 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002685 main.cleanup()
2686 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002687 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002688 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002689 main.cleanup()
2690 main.exit()
2691
You Wang3c276252016-09-21 15:21:36 -07002692 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002693 """
2694 Determine the number of flow rules for the given device id that are
2695 in the added state
You Wang3c276252016-09-21 15:21:36 -07002696 Params:
2697 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002698 """
2699 try:
You Wang3c276252016-09-21 15:21:36 -07002700 if core:
2701 cmdStr = "flows any " + str( deviceId ) + " | " +\
2702 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2703 else:
2704 cmdStr = "flows any " + str( deviceId ) + " | " +\
2705 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002706 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002707 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002708 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002709 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002710 except AssertionError:
2711 main.log.exception( "" )
2712 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002713 except pexpect.EOF:
2714 main.log.error( self.name + ": EOF exception found" )
2715 main.log.error( self.name + ": " + self.handle.before )
2716 main.cleanup()
2717 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002718 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002719 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002720 main.cleanup()
2721 main.exit()
2722
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002724 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002725 Use 'devices' function to obtain list of all devices
2726 and parse the result to obtain a list of all device
2727 id's. Returns this list. Returns empty list if no
2728 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002729 List is ordered sequentially
2730
andrewonlab3e15ead2014-10-15 14:21:34 -04002731 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002732 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002733 the ids. By obtaining the list of device ids on the fly,
2734 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002735 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002736 try:
kelvin8ec71442015-01-15 16:57:00 -08002737 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002738 devicesStr = self.devices( jsonFormat=False )
2739 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002740
kelvin-onlabd3b64892015-01-20 13:26:24 -08002741 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002742 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002743 return idList
kelvin8ec71442015-01-15 16:57:00 -08002744
2745 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002746 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002747 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002748 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002749 # Split list further into arguments before and after string
2750 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002751 # append to idList
2752 for arg in tempList:
2753 idList.append( arg.split( "id=" )[ 1 ] )
2754 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002755
Jon Halld4d4b372015-01-28 16:02:41 -08002756 except TypeError:
2757 main.log.exception( self.name + ": Object not as expected" )
2758 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002760 main.log.error( self.name + ": EOF exception found" )
2761 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002762 main.cleanup()
2763 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002764 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002765 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002766 main.cleanup()
2767 main.exit()
2768
kelvin-onlabd3b64892015-01-20 13:26:24 -08002769 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002770 """
andrewonlab7c211572014-10-15 16:45:20 -04002771 Uses 'nodes' function to obtain list of all nodes
2772 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002773 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002774 Returns:
2775 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002776 """
andrewonlab7c211572014-10-15 16:45:20 -04002777 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002778 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002779 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002780 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002781 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002782 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002783 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002784 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002785 nodesJson = json.loads( nodesStr )
2786 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002787 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002788 except ( TypeError, ValueError ):
2789 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002790 return None
andrewonlab7c211572014-10-15 16:45:20 -04002791 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002792 main.log.error( self.name + ": EOF exception found" )
2793 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002794 main.cleanup()
2795 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002796 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002797 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002798 main.cleanup()
2799 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002800
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002802 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002803 Return the first device from the devices api whose 'id' contains 'dpid'
2804 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002805 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002806 try:
kelvin8ec71442015-01-15 16:57:00 -08002807 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002808 return None
2809 else:
kelvin8ec71442015-01-15 16:57:00 -08002810 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 rawDevices = self.devices()
2812 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002813 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002815 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2816 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002817 return device
2818 return None
Jon Hallc6793552016-01-19 14:18:37 -08002819 except ( TypeError, ValueError ):
2820 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002821 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002822 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002823 main.log.error( self.name + ": EOF exception found" )
2824 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002825 main.cleanup()
2826 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002827 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002828 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002829 main.cleanup()
2830 main.exit()
2831
You Wang24139872016-05-03 11:48:47 -07002832 def getTopology( self, topologyOutput ):
2833 """
2834 Definition:
2835 Loads a json topology output
2836 Return:
2837 topology = current ONOS topology
2838 """
2839 import json
2840 try:
2841 # either onos:topology or 'topology' will work in CLI
2842 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002843 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002844 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002845 except ( TypeError, ValueError ):
2846 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2847 return None
You Wang24139872016-05-03 11:48:47 -07002848 except pexpect.EOF:
2849 main.log.error( self.name + ": EOF exception found" )
2850 main.log.error( self.name + ": " + self.handle.before )
2851 main.cleanup()
2852 main.exit()
2853 except Exception:
2854 main.log.exception( self.name + ": Uncaught exception!" )
2855 main.cleanup()
2856 main.exit()
2857
Flavio Castro82ee2f62016-06-07 15:04:12 -07002858 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002859 """
Jon Hallefbd9792015-03-05 16:11:36 -08002860 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002861 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002862 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002863
Flavio Castro82ee2f62016-06-07 15:04:12 -07002864 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002865 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002866 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002867 logLevel = level to log to.
2868 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002869
Jon Hallefbd9792015-03-05 16:11:36 -08002870 Returns: main.TRUE if the number of switches and links are correct,
2871 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002872 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002873 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002874 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002875 try:
You Wang13310252016-07-31 10:56:14 -07002876 summary = self.summary()
2877 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002878 except ( TypeError, ValueError ):
2879 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2880 return main.ERROR
2881 try:
2882 topology = self.getTopology( self.topology() )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002883 if topology == {} or topology == None or summary == {} or summary == None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002884 return main.ERROR
2885 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002886 # Is the number of switches is what we expected
2887 devices = topology.get( 'devices', False )
2888 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002889 nodes = summary.get( 'nodes', False )
2890 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002891 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002892 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002893 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002894 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002895 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2896 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002897 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002898 output = output + "The number of links and switches match "\
2899 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002900 result = main.TRUE
2901 else:
You Wang24139872016-05-03 11:48:47 -07002902 output = output + \
2903 "The number of links and switches does not match " + \
2904 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002905 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002906 output = output + "\n ONOS sees %i devices" % int( devices )
2907 output = output + " (%i expected) " % int( numoswitch )
2908 output = output + "and %i links " % int( links )
2909 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002910 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002911 output = output + "and %i controllers " % int( nodes )
2912 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002914 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002915 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002916 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002917 else:
You Wang24139872016-05-03 11:48:47 -07002918 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002919 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002920 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002921 main.log.error( self.name + ": EOF exception found" )
2922 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002923 main.cleanup()
2924 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002926 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002927 main.cleanup()
2928 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002929
kelvin-onlabd3b64892015-01-20 13:26:24 -08002930 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002931 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002932 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002933 deviceId must be the id of a device as seen in the onos devices command
2934 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002935 role must be either master, standby, or none
2936
Jon Halle3f39ff2015-01-13 11:50:53 -08002937 Returns:
2938 main.TRUE or main.FALSE based on argument verification and
2939 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002940 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002941 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002942 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002943 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002944 cmdStr = "device-role " +\
2945 str( deviceId ) + " " +\
2946 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002947 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002948 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002949 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002950 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002951 if re.search( "Error", handle ):
2952 # end color output to escape any colours
2953 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002954 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002955 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002956 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002957 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002958 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002959 main.log.error( "Invalid 'role' given to device_role(). " +
2960 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002961 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002962 except AssertionError:
2963 main.log.exception( "" )
2964 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002965 except TypeError:
2966 main.log.exception( self.name + ": Object not as expected" )
2967 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002968 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002969 main.log.error( self.name + ": EOF exception found" )
2970 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04002971 main.cleanup()
2972 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002973 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002974 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04002975 main.cleanup()
2976 main.exit()
2977
kelvin-onlabd3b64892015-01-20 13:26:24 -08002978 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002979 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002980 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002981 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002983 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002984 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002985 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002987 cmdStr += " -j"
2988 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002989 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002990 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002991 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002992 except AssertionError:
2993 main.log.exception( "" )
2994 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002995 except TypeError:
2996 main.log.exception( self.name + ": Object not as expected" )
2997 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08002998 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002999 main.log.error( self.name + ": EOF exception found" )
3000 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003001 main.cleanup()
3002 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003003 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003004 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003005 main.cleanup()
3006 main.exit()
3007
kelvin-onlabd3b64892015-01-20 13:26:24 -08003008 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003010 CLI command to get the current leader for the Election test application
3011 NOTE: Requires installation of the onos-app-election feature
3012 Returns: Node IP of the leader if one exists
3013 None if none exists
3014 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003015 """
Jon Hall94fd0472014-12-08 11:52:42 -08003016 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003017 cmdStr = "election-test-leader"
3018 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003019 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003020 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003021 # Leader
3022 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003023 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003024 nodeSearch = re.search( leaderPattern, response )
3025 if nodeSearch:
3026 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003027 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003028 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003029 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003030 # no leader
3031 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003033 nullSearch = re.search( nullPattern, response )
3034 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003035 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003036 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003037 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003038 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003039 main.log.error( "Error in electionTestLeader on " + self.name +
3040 ": " + "unexpected response" )
3041 main.log.error( repr( response ) )
3042 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003043 except AssertionError:
3044 main.log.exception( "" )
3045 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003046 except TypeError:
3047 main.log.exception( self.name + ": Object not as expected" )
3048 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003049 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003050 main.log.error( self.name + ": EOF exception found" )
3051 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003052 main.cleanup()
3053 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003054 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003055 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003056 main.cleanup()
3057 main.exit()
3058
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003060 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003061 CLI command to run for leadership of the Election test application.
3062 NOTE: Requires installation of the onos-app-election feature
3063 Returns: Main.TRUE on success
3064 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003065 """
Jon Hall94fd0472014-12-08 11:52:42 -08003066 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003067 cmdStr = "election-test-run"
3068 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003069 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003070 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003071 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003072 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003074 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003075 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003076 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003077 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003078 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003079 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003080 main.log.error( "Error in electionTestRun on " + self.name +
3081 ": " + "unexpected response" )
3082 main.log.error( repr( response ) )
3083 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003084 except AssertionError:
3085 main.log.exception( "" )
3086 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003087 except TypeError:
3088 main.log.exception( self.name + ": Object not as expected" )
3089 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003091 main.log.error( self.name + ": EOF exception found" )
3092 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003093 main.cleanup()
3094 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003095 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003096 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003097 main.cleanup()
3098 main.exit()
3099
kelvin-onlabd3b64892015-01-20 13:26:24 -08003100 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003101 """
Jon Hall94fd0472014-12-08 11:52:42 -08003102 * CLI command to withdraw the local node from leadership election for
3103 * the Election test application.
3104 #NOTE: Requires installation of the onos-app-election feature
3105 Returns: Main.TRUE on success
3106 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003107 """
Jon Hall94fd0472014-12-08 11:52:42 -08003108 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 cmdStr = "election-test-withdraw"
3110 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003111 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003112 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003113 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003114 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003115 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 if re.search( successPattern, response ):
3117 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003119 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003120 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003121 main.log.error( "Error in electionTestWithdraw on " +
3122 self.name + ": " + "unexpected response" )
3123 main.log.error( repr( response ) )
3124 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003125 except AssertionError:
3126 main.log.exception( "" )
3127 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003128 except TypeError:
3129 main.log.exception( self.name + ": Object not as expected" )
3130 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003131 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003132 main.log.error( self.name + ": EOF exception found" )
3133 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003134 main.cleanup()
3135 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003137 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003138 main.cleanup()
3139 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003140
kelvin8ec71442015-01-15 16:57:00 -08003141 def getDevicePortsEnabledCount( self, dpid ):
3142 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003143 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003144 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003145 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003146 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003147 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3148 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003149 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003150 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003151 if re.search( "No such device", output ):
3152 main.log.error( "Error in getting ports" )
3153 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003154 return output
Jon Hallc6793552016-01-19 14:18:37 -08003155 except AssertionError:
3156 main.log.exception( "" )
3157 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003158 except TypeError:
3159 main.log.exception( self.name + ": Object not as expected" )
3160 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003161 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003162 main.log.error( self.name + ": EOF exception found" )
3163 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164 main.cleanup()
3165 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003166 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003167 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003168 main.cleanup()
3169 main.exit()
3170
kelvin8ec71442015-01-15 16:57:00 -08003171 def getDeviceLinksActiveCount( self, dpid ):
3172 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003173 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003174 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003175 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003176 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003177 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3178 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003179 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003180 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003181 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003182 main.log.error( "Error in getting ports " )
3183 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003184 return output
Jon Hallc6793552016-01-19 14:18:37 -08003185 except AssertionError:
3186 main.log.exception( "" )
3187 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003188 except TypeError:
3189 main.log.exception( self.name + ": Object not as expected" )
3190 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003192 main.log.error( self.name + ": EOF exception found" )
3193 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003194 main.cleanup()
3195 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003196 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003197 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003198 main.cleanup()
3199 main.exit()
3200
kelvin8ec71442015-01-15 16:57:00 -08003201 def getAllIntentIds( self ):
3202 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003203 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003204 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003205 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003206 cmdStr = "onos:intents | grep id="
3207 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003208 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003209 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003210 if re.search( "Error", output ):
3211 main.log.error( "Error in getting ports" )
3212 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003213 return output
Jon Hallc6793552016-01-19 14:18:37 -08003214 except AssertionError:
3215 main.log.exception( "" )
3216 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003217 except TypeError:
3218 main.log.exception( self.name + ": Object not as expected" )
3219 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003220 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003221 main.log.error( self.name + ": EOF exception found" )
3222 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003223 main.cleanup()
3224 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003225 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003226 main.log.exception( self.name + ": Uncaught exception!" )
3227 main.cleanup()
3228 main.exit()
3229
Jon Hall73509952015-02-24 16:42:56 -08003230 def intentSummary( self ):
3231 """
Jon Hallefbd9792015-03-05 16:11:36 -08003232 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003233 """
3234 try:
3235 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003236 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003237 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003238 states.append( intent.get( 'state', None ) )
3239 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003240 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003241 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003242 except ( TypeError, ValueError ):
3243 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003244 return None
3245 except pexpect.EOF:
3246 main.log.error( self.name + ": EOF exception found" )
3247 main.log.error( self.name + ": " + self.handle.before )
3248 main.cleanup()
3249 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003250 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003251 main.log.exception( self.name + ": Uncaught exception!" )
3252 main.cleanup()
3253 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003254
Jon Hall61282e32015-03-19 11:34:11 -07003255 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003256 """
3257 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003258 Optional argument:
3259 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003260 """
Jon Hall63604932015-02-26 17:09:50 -08003261 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003262 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003263 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003264 cmdStr += " -j"
3265 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003266 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003267 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003268 return output
Jon Hallc6793552016-01-19 14:18:37 -08003269 except AssertionError:
3270 main.log.exception( "" )
3271 return None
Jon Hall63604932015-02-26 17:09:50 -08003272 except TypeError:
3273 main.log.exception( self.name + ": Object not as expected" )
3274 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003275 except pexpect.EOF:
3276 main.log.error( self.name + ": EOF exception found" )
3277 main.log.error( self.name + ": " + self.handle.before )
3278 main.cleanup()
3279 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003280 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003281 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003282 main.cleanup()
3283 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003284
acsmarsa4a4d1e2015-07-10 16:01:24 -07003285 def leaderCandidates( self, jsonFormat=True ):
3286 """
3287 Returns the output of the leaders -c command.
3288 Optional argument:
3289 * jsonFormat - boolean indicating if you want output in json
3290 """
3291 try:
3292 cmdStr = "onos:leaders -c"
3293 if jsonFormat:
3294 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
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298 return output
Jon Hallc6793552016-01-19 14:18:37 -08003299 except AssertionError:
3300 main.log.exception( "" )
3301 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003302 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()
3310 except Exception:
3311 main.log.exception( self.name + ": Uncaught exception!" )
3312 main.cleanup()
3313 main.exit()
3314
Jon Hallc6793552016-01-19 14:18:37 -08003315 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003316 """
3317 Returns a list in format [leader,candidate1,candidate2,...] for a given
3318 topic parameter and an empty list if the topic doesn't exist
3319 If no leader is elected leader in the returned list will be "none"
3320 Returns None if there is a type error processing the json object
3321 """
3322 try:
Jon Hall6e709752016-02-01 13:38:46 -08003323 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003324 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003325 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003326 assert "Command not found:" not in rawOutput, rawOutput
3327 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003328 results = []
3329 for dict in output:
3330 if dict["topic"] == topic:
3331 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003332 candidates = re.split( ", ", dict["candidates"][1:-1] )
3333 results.append( leader )
3334 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003335 return results
Jon Hallc6793552016-01-19 14:18:37 -08003336 except AssertionError:
3337 main.log.exception( "" )
3338 return None
3339 except ( TypeError, ValueError ):
3340 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003341 return None
3342 except pexpect.EOF:
3343 main.log.error( self.name + ": EOF exception found" )
3344 main.log.error( self.name + ": " + self.handle.before )
3345 main.cleanup()
3346 main.exit()
3347 except Exception:
3348 main.log.exception( self.name + ": Uncaught exception!" )
3349 main.cleanup()
3350 main.exit()
3351
Jon Hall61282e32015-03-19 11:34:11 -07003352 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003353 """
3354 Returns the output of the intent Pending map.
3355 """
Jon Hall63604932015-02-26 17:09:50 -08003356 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003357 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003358 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003359 cmdStr += " -j"
3360 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003361 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003362 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003363 return output
Jon Hallc6793552016-01-19 14:18:37 -08003364 except AssertionError:
3365 main.log.exception( "" )
3366 return None
Jon Hall63604932015-02-26 17:09:50 -08003367 except TypeError:
3368 main.log.exception( self.name + ": Object not as expected" )
3369 return None
3370 except pexpect.EOF:
3371 main.log.error( self.name + ": EOF exception found" )
3372 main.log.error( self.name + ": " + self.handle.before )
3373 main.cleanup()
3374 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003375 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003376 main.log.exception( self.name + ": Uncaught exception!" )
3377 main.cleanup()
3378 main.exit()
3379
Jon Hall2c8959e2016-12-16 12:17:34 -08003380 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003381 """
3382 Returns the output of the raft partitions command for ONOS.
3383 """
Jon Hall61282e32015-03-19 11:34:11 -07003384 # Sample JSON
3385 # {
3386 # "leader": "tcp://10.128.30.11:7238",
3387 # "members": [
3388 # "tcp://10.128.30.11:7238",
3389 # "tcp://10.128.30.17:7238",
3390 # "tcp://10.128.30.13:7238",
3391 # ],
3392 # "name": "p1",
3393 # "term": 3
3394 # },
Jon Hall63604932015-02-26 17:09:50 -08003395 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003396 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003397 if candidates:
3398 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003399 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003400 cmdStr += " -j"
3401 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003402 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003403 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003404 return output
Jon Hallc6793552016-01-19 14:18:37 -08003405 except AssertionError:
3406 main.log.exception( "" )
3407 return None
Jon Hall63604932015-02-26 17:09:50 -08003408 except TypeError:
3409 main.log.exception( self.name + ": Object not as expected" )
3410 return None
3411 except pexpect.EOF:
3412 main.log.error( self.name + ": EOF exception found" )
3413 main.log.error( self.name + ": " + self.handle.before )
3414 main.cleanup()
3415 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003416 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003417 main.log.exception( self.name + ": Uncaught exception!" )
3418 main.cleanup()
3419 main.exit()
3420
Jon Halle9f909e2016-09-23 10:43:12 -07003421 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003422 """
3423 Returns the output of the apps command for ONOS. This command lists
3424 information about installed ONOS applications
3425 """
3426 # Sample JSON object
3427 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3428 # "description":"ONOS OpenFlow protocol southbound providers",
3429 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3430 # "features":"[onos-openflow]","state":"ACTIVE"}]
3431 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003432 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003433 if summary:
3434 cmdStr += " -s"
3435 if active:
3436 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003437 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003438 cmdStr += " -j"
3439 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003440 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003441 assert "Command not found:" not in output, output
3442 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003443 return output
Jon Hallbe379602015-03-24 13:39:32 -07003444 # FIXME: look at specific exceptions/Errors
3445 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003446 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003447 return None
3448 except TypeError:
3449 main.log.exception( self.name + ": Object not as expected" )
3450 return None
3451 except pexpect.EOF:
3452 main.log.error( self.name + ": EOF exception found" )
3453 main.log.error( self.name + ": " + self.handle.before )
3454 main.cleanup()
3455 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003456 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003457 main.log.exception( self.name + ": Uncaught exception!" )
3458 main.cleanup()
3459 main.exit()
3460
Jon Hall146f1522015-03-24 15:33:24 -07003461 def appStatus( self, appName ):
3462 """
3463 Uses the onos:apps cli command to return the status of an application.
3464 Returns:
3465 "ACTIVE" - If app is installed and activated
3466 "INSTALLED" - If app is installed and deactivated
3467 "UNINSTALLED" - If app is not installed
3468 None - on error
3469 """
Jon Hall146f1522015-03-24 15:33:24 -07003470 try:
3471 if not isinstance( appName, types.StringType ):
3472 main.log.error( self.name + ".appStatus(): appName must be" +
3473 " a string" )
3474 return None
3475 output = self.apps( jsonFormat=True )
3476 appsJson = json.loads( output )
3477 state = None
3478 for app in appsJson:
3479 if appName == app.get('name'):
3480 state = app.get('state')
3481 break
3482 if state == "ACTIVE" or state == "INSTALLED":
3483 return state
3484 elif state is None:
3485 return "UNINSTALLED"
3486 elif state:
3487 main.log.error( "Unexpected state from 'onos:apps': " +
3488 str( state ) )
3489 return state
Jon Hallc6793552016-01-19 14:18:37 -08003490 except ( TypeError, ValueError ):
3491 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003492 return None
3493 except pexpect.EOF:
3494 main.log.error( self.name + ": EOF exception found" )
3495 main.log.error( self.name + ": " + self.handle.before )
3496 main.cleanup()
3497 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003498 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003499 main.log.exception( self.name + ": Uncaught exception!" )
3500 main.cleanup()
3501 main.exit()
3502
Jon Hallbe379602015-03-24 13:39:32 -07003503 def app( self, appName, option ):
3504 """
3505 Interacts with the app command for ONOS. This command manages
3506 application inventory.
3507 """
Jon Hallbe379602015-03-24 13:39:32 -07003508 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003509 # Validate argument types
3510 valid = True
3511 if not isinstance( appName, types.StringType ):
3512 main.log.error( self.name + ".app(): appName must be a " +
3513 "string" )
3514 valid = False
3515 if not isinstance( option, types.StringType ):
3516 main.log.error( self.name + ".app(): option must be a string" )
3517 valid = False
3518 if not valid:
3519 return main.FALSE
3520 # Validate Option
3521 option = option.lower()
3522 # NOTE: Install may become a valid option
3523 if option == "activate":
3524 pass
3525 elif option == "deactivate":
3526 pass
3527 elif option == "uninstall":
3528 pass
3529 else:
3530 # Invalid option
3531 main.log.error( "The ONOS app command argument only takes " +
3532 "the values: (activate|deactivate|uninstall)" +
3533 "; was given '" + option + "'")
3534 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003535 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003536 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003537 assert output is not None, "Error in sendline"
3538 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003539 if "Error executing command" in output:
3540 main.log.error( "Error in processing onos:app command: " +
3541 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003542 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003543 elif "No such application" in output:
3544 main.log.error( "The application '" + appName +
3545 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003546 return main.FALSE
3547 elif "Command not found:" in output:
3548 main.log.error( "Error in processing onos:app command: " +
3549 str( output ) )
3550 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003551 elif "Unsupported command:" in output:
3552 main.log.error( "Incorrect command given to 'app': " +
3553 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003554 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003555 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003556 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003557 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003558 except AssertionError:
3559 main.log.exception( self.name + ": AssertionError exception found" )
3560 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003561 except TypeError:
3562 main.log.exception( self.name + ": Object not as expected" )
3563 return main.ERROR
3564 except pexpect.EOF:
3565 main.log.error( self.name + ": EOF exception found" )
3566 main.log.error( self.name + ": " + self.handle.before )
3567 main.cleanup()
3568 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003569 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003570 main.log.exception( self.name + ": Uncaught exception!" )
3571 main.cleanup()
3572 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003573
Jon Hallbd16b922015-03-26 17:53:15 -07003574 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003575 """
3576 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003577 appName is the hierarchical app name, not the feature name
3578 If check is True, method will check the status of the app after the
3579 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003580 Returns main.TRUE if the command was successfully sent
3581 main.FALSE if the cli responded with an error or given
3582 incorrect input
3583 """
3584 try:
3585 if not isinstance( appName, types.StringType ):
3586 main.log.error( self.name + ".activateApp(): appName must be" +
3587 " a string" )
3588 return main.FALSE
3589 status = self.appStatus( appName )
3590 if status == "INSTALLED":
3591 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003592 if check and response == main.TRUE:
3593 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003594 status = self.appStatus( appName )
3595 if status == "ACTIVE":
3596 return main.TRUE
3597 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003598 main.log.debug( "The state of application " +
3599 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003600 time.sleep( 1 )
3601 return main.FALSE
3602 else: # not 'check' or command didn't succeed
3603 return response
Jon Hall146f1522015-03-24 15:33:24 -07003604 elif status == "ACTIVE":
3605 return main.TRUE
3606 elif status == "UNINSTALLED":
3607 main.log.error( self.name + ": Tried to activate the " +
3608 "application '" + appName + "' which is not " +
3609 "installed." )
3610 else:
3611 main.log.error( "Unexpected return value from appStatus: " +
3612 str( status ) )
3613 return main.ERROR
3614 except TypeError:
3615 main.log.exception( self.name + ": Object not as expected" )
3616 return main.ERROR
3617 except pexpect.EOF:
3618 main.log.error( self.name + ": EOF exception found" )
3619 main.log.error( self.name + ": " + self.handle.before )
3620 main.cleanup()
3621 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003622 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003623 main.log.exception( self.name + ": Uncaught exception!" )
3624 main.cleanup()
3625 main.exit()
3626
Jon Hallbd16b922015-03-26 17:53:15 -07003627 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003628 """
3629 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003630 appName is the hierarchical app name, not the feature name
3631 If check is True, method will check the status of the app after the
3632 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003633 Returns main.TRUE if the command was successfully sent
3634 main.FALSE if the cli responded with an error or given
3635 incorrect input
3636 """
3637 try:
3638 if not isinstance( appName, types.StringType ):
3639 main.log.error( self.name + ".deactivateApp(): appName must " +
3640 "be a string" )
3641 return main.FALSE
3642 status = self.appStatus( appName )
3643 if status == "INSTALLED":
3644 return main.TRUE
3645 elif status == "ACTIVE":
3646 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003647 if check and response == main.TRUE:
3648 for i in range(10): # try 10 times then give up
3649 status = self.appStatus( appName )
3650 if status == "INSTALLED":
3651 return main.TRUE
3652 else:
3653 time.sleep( 1 )
3654 return main.FALSE
3655 else: # not check or command didn't succeed
3656 return response
Jon Hall146f1522015-03-24 15:33:24 -07003657 elif status == "UNINSTALLED":
3658 main.log.warn( self.name + ": Tried to deactivate the " +
3659 "application '" + appName + "' which is not " +
3660 "installed." )
3661 return main.TRUE
3662 else:
3663 main.log.error( "Unexpected return value from appStatus: " +
3664 str( status ) )
3665 return main.ERROR
3666 except TypeError:
3667 main.log.exception( self.name + ": Object not as expected" )
3668 return main.ERROR
3669 except pexpect.EOF:
3670 main.log.error( self.name + ": EOF exception found" )
3671 main.log.error( self.name + ": " + self.handle.before )
3672 main.cleanup()
3673 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003674 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003675 main.log.exception( self.name + ": Uncaught exception!" )
3676 main.cleanup()
3677 main.exit()
3678
Jon Hallbd16b922015-03-26 17:53:15 -07003679 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003680 """
3681 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003682 appName is the hierarchical app name, not the feature name
3683 If check is True, method will check the status of the app after the
3684 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003685 Returns main.TRUE if the command was successfully sent
3686 main.FALSE if the cli responded with an error or given
3687 incorrect input
3688 """
3689 # TODO: check with Thomas about the state machine for apps
3690 try:
3691 if not isinstance( appName, types.StringType ):
3692 main.log.error( self.name + ".uninstallApp(): appName must " +
3693 "be a string" )
3694 return main.FALSE
3695 status = self.appStatus( appName )
3696 if status == "INSTALLED":
3697 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003698 if check and response == main.TRUE:
3699 for i in range(10): # try 10 times then give up
3700 status = self.appStatus( appName )
3701 if status == "UNINSTALLED":
3702 return main.TRUE
3703 else:
3704 time.sleep( 1 )
3705 return main.FALSE
3706 else: # not check or command didn't succeed
3707 return response
Jon Hall146f1522015-03-24 15:33:24 -07003708 elif status == "ACTIVE":
3709 main.log.warn( self.name + ": Tried to uninstall the " +
3710 "application '" + appName + "' which is " +
3711 "currently active." )
3712 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003713 if check and response == main.TRUE:
3714 for i in range(10): # try 10 times then give up
3715 status = self.appStatus( appName )
3716 if status == "UNINSTALLED":
3717 return main.TRUE
3718 else:
3719 time.sleep( 1 )
3720 return main.FALSE
3721 else: # not check or command didn't succeed
3722 return response
Jon Hall146f1522015-03-24 15:33:24 -07003723 elif status == "UNINSTALLED":
3724 return main.TRUE
3725 else:
3726 main.log.error( "Unexpected return value from appStatus: " +
3727 str( status ) )
3728 return main.ERROR
3729 except TypeError:
3730 main.log.exception( self.name + ": Object not as expected" )
3731 return main.ERROR
3732 except pexpect.EOF:
3733 main.log.error( self.name + ": EOF exception found" )
3734 main.log.error( self.name + ": " + self.handle.before )
3735 main.cleanup()
3736 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003737 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003738 main.log.exception( self.name + ": Uncaught exception!" )
3739 main.cleanup()
3740 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003741
3742 def appIDs( self, jsonFormat=True ):
3743 """
3744 Show the mappings between app id and app names given by the 'app-ids'
3745 cli command
3746 """
3747 try:
3748 cmdStr = "app-ids"
3749 if jsonFormat:
3750 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003751 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003752 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003753 assert "Command not found:" not in output, output
3754 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003755 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003756 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003757 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003758 return None
3759 except TypeError:
3760 main.log.exception( self.name + ": Object not as expected" )
3761 return None
3762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
3765 main.cleanup()
3766 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003767 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003768 main.log.exception( self.name + ": Uncaught exception!" )
3769 main.cleanup()
3770 main.exit()
3771
3772 def appToIDCheck( self ):
3773 """
3774 This method will check that each application's ID listed in 'apps' is
3775 the same as the ID listed in 'app-ids'. The check will also check that
3776 there are no duplicate IDs issued. Note that an app ID should be
3777 a globaly unique numerical identifier for app/app-like features. Once
3778 an ID is registered, the ID is never freed up so that if an app is
3779 reinstalled it will have the same ID.
3780
3781 Returns: main.TRUE if the check passes and
3782 main.FALSE if the check fails or
3783 main.ERROR if there is some error in processing the test
3784 """
3785 try:
Jon Hall390696c2015-05-05 17:13:41 -07003786 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003787 rawJson = self.appIDs( jsonFormat=True )
3788 if rawJson:
3789 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003790 else:
Jon Hallc6793552016-01-19 14:18:37 -08003791 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003792 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003793 rawJson = self.apps( jsonFormat=True )
3794 if rawJson:
3795 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003796 else:
Jon Hallc6793552016-01-19 14:18:37 -08003797 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003798 bail = True
3799 if bail:
3800 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003801 result = main.TRUE
3802 for app in apps:
3803 appID = app.get( 'id' )
3804 if appID is None:
3805 main.log.error( "Error parsing app: " + str( app ) )
3806 result = main.FALSE
3807 appName = app.get( 'name' )
3808 if appName is None:
3809 main.log.error( "Error parsing app: " + str( app ) )
3810 result = main.FALSE
3811 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003812 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003813 # main.log.debug( "Comparing " + str( app ) + " to " +
3814 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003815 if not current: # if ids doesn't have this id
3816 result = main.FALSE
3817 main.log.error( "'app-ids' does not have the ID for " +
3818 str( appName ) + " that apps does." )
3819 elif len( current ) > 1:
3820 # there is more than one app with this ID
3821 result = main.FALSE
3822 # We will log this later in the method
3823 elif not current[0][ 'name' ] == appName:
3824 currentName = current[0][ 'name' ]
3825 result = main.FALSE
3826 main.log.error( "'app-ids' has " + str( currentName ) +
3827 " registered under id:" + str( appID ) +
3828 " but 'apps' has " + str( appName ) )
3829 else:
3830 pass # id and name match!
3831 # now make sure that app-ids has no duplicates
3832 idsList = []
3833 namesList = []
3834 for item in ids:
3835 idsList.append( item[ 'id' ] )
3836 namesList.append( item[ 'name' ] )
3837 if len( idsList ) != len( set( idsList ) ) or\
3838 len( namesList ) != len( set( namesList ) ):
3839 main.log.error( "'app-ids' has some duplicate entries: \n"
3840 + json.dumps( ids,
3841 sort_keys=True,
3842 indent=4,
3843 separators=( ',', ': ' ) ) )
3844 result = main.FALSE
3845 return result
Jon Hallc6793552016-01-19 14:18:37 -08003846 except ( TypeError, ValueError ):
3847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003848 return main.ERROR
3849 except pexpect.EOF:
3850 main.log.error( self.name + ": EOF exception found" )
3851 main.log.error( self.name + ": " + self.handle.before )
3852 main.cleanup()
3853 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003854 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003855 main.log.exception( self.name + ": Uncaught exception!" )
3856 main.cleanup()
3857 main.exit()
3858
Jon Hallfb760a02015-04-13 15:35:03 -07003859 def getCfg( self, component=None, propName=None, short=False,
3860 jsonFormat=True ):
3861 """
3862 Get configuration settings from onos cli
3863 Optional arguments:
3864 component - Optionally only list configurations for a specific
3865 component. If None, all components with configurations
3866 are displayed. Case Sensitive string.
3867 propName - If component is specified, propName option will show
3868 only this specific configuration from that component.
3869 Case Sensitive string.
3870 jsonFormat - Returns output as json. Note that this will override
3871 the short option
3872 short - Short, less verbose, version of configurations.
3873 This is overridden by the json option
3874 returns:
3875 Output from cli as a string or None on error
3876 """
3877 try:
3878 baseStr = "cfg"
3879 cmdStr = " get"
3880 componentStr = ""
3881 if component:
3882 componentStr += " " + component
3883 if propName:
3884 componentStr += " " + propName
3885 if jsonFormat:
3886 baseStr += " -j"
3887 elif short:
3888 baseStr += " -s"
3889 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003890 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003891 assert "Command not found:" not in output, output
3892 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003893 return output
3894 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003895 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003896 return None
3897 except TypeError:
3898 main.log.exception( self.name + ": Object not as expected" )
3899 return None
3900 except pexpect.EOF:
3901 main.log.error( self.name + ": EOF exception found" )
3902 main.log.error( self.name + ": " + self.handle.before )
3903 main.cleanup()
3904 main.exit()
3905 except Exception:
3906 main.log.exception( self.name + ": Uncaught exception!" )
3907 main.cleanup()
3908 main.exit()
3909
3910 def setCfg( self, component, propName, value=None, check=True ):
3911 """
3912 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003913 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003914 component - The case sensitive name of the component whose
3915 property is to be set
3916 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003917 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003918 value - The value to set the property to. If None, will unset the
3919 property and revert it to it's default value(if applicable)
3920 check - Boolean, Check whether the option was successfully set this
3921 only applies when a value is given.
3922 returns:
3923 main.TRUE on success or main.FALSE on failure. If check is False,
3924 will return main.TRUE unless there is an error
3925 """
3926 try:
3927 baseStr = "cfg"
3928 cmdStr = " set " + str( component ) + " " + str( propName )
3929 if value is not None:
3930 cmdStr += " " + str( value )
3931 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003932 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003933 assert "Command not found:" not in output, output
3934 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003935 if value and check:
3936 results = self.getCfg( component=str( component ),
3937 propName=str( propName ),
3938 jsonFormat=True )
3939 # Check if current value is what we just set
3940 try:
3941 jsonOutput = json.loads( results )
3942 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003943 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003944 main.log.exception( "Error parsing cfg output" )
3945 main.log.error( "output:" + repr( results ) )
3946 return main.FALSE
3947 if current == str( value ):
3948 return main.TRUE
3949 return main.FALSE
3950 return main.TRUE
3951 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003952 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003953 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003954 except ( TypeError, ValueError ):
3955 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003956 return main.FALSE
3957 except pexpect.EOF:
3958 main.log.error( self.name + ": EOF exception found" )
3959 main.log.error( self.name + ": " + self.handle.before )
3960 main.cleanup()
3961 main.exit()
3962 except Exception:
3963 main.log.exception( self.name + ": Uncaught exception!" )
3964 main.cleanup()
3965 main.exit()
3966
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003967 def distPrimitivesSend( self, cmd ):
3968 """
3969 Function to handle sending cli commands for the distributed primitives test app
3970
3971 This command will catch some exceptions and retry the command on some
3972 specific store exceptions.
3973
3974 Required arguments:
3975 cmd - The command to send to the cli
3976 returns:
3977 string containing the cli output
3978 None on Error
3979 """
3980 try:
3981 output = self.sendline( cmd )
3982 try:
3983 assert output is not None, "Error in sendline"
3984 # TODO: Maybe make this less hardcoded
3985 # ConsistentMap Exceptions
3986 assert "org.onosproject.store.service" not in output
3987 # Node not leader
3988 assert "java.lang.IllegalStateException" not in output
3989 except AssertionError:
3990 main.log.error( "Error in processing '" + cmd + "' " +
3991 "command: " + str( output ) )
3992 retryTime = 30 # Conservative time, given by Madan
3993 main.log.info( "Waiting " + str( retryTime ) +
3994 "seconds before retrying." )
3995 time.sleep( retryTime ) # Due to change in mastership
3996 output = self.sendline( cmd )
3997 assert output is not None, "Error in sendline"
3998 assert "Command not found:" not in output, output
3999 assert "Error executing command" not in output, output
4000 main.log.info( self.name + ": " + output )
4001 return output
4002 except AssertionError:
4003 main.log.exception( "Error in processing '" + cmd + "' command." )
4004 return None
4005 except TypeError:
4006 main.log.exception( self.name + ": Object not as expected" )
4007 return None
4008 except pexpect.EOF:
4009 main.log.error( self.name + ": EOF exception found" )
4010 main.log.error( self.name + ": " + self.handle.before )
4011 main.cleanup()
4012 main.exit()
4013 except Exception:
4014 main.log.exception( self.name + ": Uncaught exception!" )
4015 main.cleanup()
4016 main.exit()
4017
Jon Hall390696c2015-05-05 17:13:41 -07004018 def setTestAdd( self, setName, values ):
4019 """
4020 CLI command to add elements to a distributed set.
4021 Arguments:
4022 setName - The name of the set to add to.
4023 values - The value(s) to add to the set, space seperated.
4024 Example usages:
4025 setTestAdd( "set1", "a b c" )
4026 setTestAdd( "set2", "1" )
4027 returns:
4028 main.TRUE on success OR
4029 main.FALSE if elements were already in the set OR
4030 main.ERROR on error
4031 """
4032 try:
4033 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004034 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004035 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4036 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004037 if re.search( positiveMatch, output):
4038 return main.TRUE
4039 elif re.search( negativeMatch, output):
4040 return main.FALSE
4041 else:
4042 main.log.error( self.name + ": setTestAdd did not" +
4043 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004044 main.log.debug( self.name + " actual: " + repr( output ) )
4045 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004046 except TypeError:
4047 main.log.exception( self.name + ": Object not as expected" )
4048 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004049 except Exception:
4050 main.log.exception( self.name + ": Uncaught exception!" )
4051 main.cleanup()
4052 main.exit()
4053
4054 def setTestRemove( self, setName, values, clear=False, retain=False ):
4055 """
4056 CLI command to remove elements from a distributed set.
4057 Required arguments:
4058 setName - The name of the set to remove from.
4059 values - The value(s) to remove from the set, space seperated.
4060 Optional arguments:
4061 clear - Clear all elements from the set
4062 retain - Retain only the given values. (intersection of the
4063 original set and the given set)
4064 returns:
4065 main.TRUE on success OR
4066 main.FALSE if the set was not changed OR
4067 main.ERROR on error
4068 """
4069 try:
4070 cmdStr = "set-test-remove "
4071 if clear:
4072 cmdStr += "-c " + str( setName )
4073 elif retain:
4074 cmdStr += "-r " + str( setName ) + " " + str( values )
4075 else:
4076 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004077 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004078 if clear:
4079 pattern = "Set " + str( setName ) + " cleared"
4080 if re.search( pattern, output ):
4081 return main.TRUE
4082 elif retain:
4083 positivePattern = str( setName ) + " was pruned to contain " +\
4084 "only elements of set \[(.*)\]"
4085 negativePattern = str( setName ) + " was not changed by " +\
4086 "retaining only elements of the set " +\
4087 "\[(.*)\]"
4088 if re.search( positivePattern, output ):
4089 return main.TRUE
4090 elif re.search( negativePattern, output ):
4091 return main.FALSE
4092 else:
4093 positivePattern = "\[(.*)\] was removed from the set " +\
4094 str( setName )
4095 if ( len( values.split() ) == 1 ):
4096 negativePattern = "\[(.*)\] was not in set " +\
4097 str( setName )
4098 else:
4099 negativePattern = "No element of \[(.*)\] was in set " +\
4100 str( setName )
4101 if re.search( positivePattern, output ):
4102 return main.TRUE
4103 elif re.search( negativePattern, output ):
4104 return main.FALSE
4105 main.log.error( self.name + ": setTestRemove did not" +
4106 " match expected output" )
4107 main.log.debug( self.name + " expected: " + pattern )
4108 main.log.debug( self.name + " actual: " + repr( output ) )
4109 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004110 except TypeError:
4111 main.log.exception( self.name + ": Object not as expected" )
4112 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004113 except Exception:
4114 main.log.exception( self.name + ": Uncaught exception!" )
4115 main.cleanup()
4116 main.exit()
4117
4118 def setTestGet( self, setName, values="" ):
4119 """
4120 CLI command to get the elements in a distributed set.
4121 Required arguments:
4122 setName - The name of the set to remove from.
4123 Optional arguments:
4124 values - The value(s) to check if in the set, space seperated.
4125 returns:
4126 main.ERROR on error OR
4127 A list of elements in the set if no optional arguments are
4128 supplied OR
4129 A tuple containing the list then:
4130 main.FALSE if the given values are not in the set OR
4131 main.TRUE if the given values are in the set OR
4132 """
4133 try:
4134 values = str( values ).strip()
4135 setName = str( setName ).strip()
4136 length = len( values.split() )
4137 containsCheck = None
4138 # Patterns to match
4139 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004140 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004141 containsTrue = "Set " + setName + " contains the value " + values
4142 containsFalse = "Set " + setName + " did not contain the value " +\
4143 values
4144 containsAllTrue = "Set " + setName + " contains the the subset " +\
4145 setPattern
4146 containsAllFalse = "Set " + setName + " did not contain the the" +\
4147 " subset " + setPattern
4148
4149 cmdStr = "set-test-get "
4150 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004151 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004152 if length == 0:
4153 match = re.search( pattern, output )
4154 else: # if given values
4155 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004156 patternTrue = pattern + "\r\n" + containsTrue
4157 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004158 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004159 patternTrue = pattern + "\r\n" + containsAllTrue
4160 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004161 matchTrue = re.search( patternTrue, output )
4162 matchFalse = re.search( patternFalse, output )
4163 if matchTrue:
4164 containsCheck = main.TRUE
4165 match = matchTrue
4166 elif matchFalse:
4167 containsCheck = main.FALSE
4168 match = matchFalse
4169 else:
4170 main.log.error( self.name + " setTestGet did not match " +\
4171 "expected output" )
4172 main.log.debug( self.name + " expected: " + pattern )
4173 main.log.debug( self.name + " actual: " + repr( output ) )
4174 match = None
4175 if match:
4176 setMatch = match.group( 1 )
4177 if setMatch == '':
4178 setList = []
4179 else:
4180 setList = setMatch.split( ", " )
4181 if length > 0:
4182 return ( setList, containsCheck )
4183 else:
4184 return setList
4185 else: # no match
4186 main.log.error( self.name + ": setTestGet did not" +
4187 " match expected output" )
4188 main.log.debug( self.name + " expected: " + pattern )
4189 main.log.debug( self.name + " actual: " + repr( output ) )
4190 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004191 except TypeError:
4192 main.log.exception( self.name + ": Object not as expected" )
4193 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004194 except Exception:
4195 main.log.exception( self.name + ": Uncaught exception!" )
4196 main.cleanup()
4197 main.exit()
4198
4199 def setTestSize( self, setName ):
4200 """
4201 CLI command to get the elements in a distributed set.
4202 Required arguments:
4203 setName - The name of the set to remove from.
4204 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004205 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004206 None on error
4207 """
4208 try:
4209 # TODO: Should this check against the number of elements returned
4210 # and then return true/false based on that?
4211 setName = str( setName ).strip()
4212 # Patterns to match
4213 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004214 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004215 setPattern
4216 cmdStr = "set-test-get -s "
4217 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004218 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004219 match = re.search( pattern, output )
4220 if match:
4221 setSize = int( match.group( 1 ) )
4222 setMatch = match.group( 2 )
4223 if len( setMatch.split() ) == setSize:
4224 main.log.info( "The size returned by " + self.name +
4225 " matches the number of elements in " +
4226 "the returned set" )
4227 else:
4228 main.log.error( "The size returned by " + self.name +
4229 " does not match the number of " +
4230 "elements in the returned set." )
4231 return setSize
4232 else: # no match
4233 main.log.error( self.name + ": setTestGet did not" +
4234 " match expected output" )
4235 main.log.debug( self.name + " expected: " + pattern )
4236 main.log.debug( self.name + " actual: " + repr( output ) )
4237 return None
Jon Hall390696c2015-05-05 17:13:41 -07004238 except TypeError:
4239 main.log.exception( self.name + ": Object not as expected" )
4240 return None
Jon Hall390696c2015-05-05 17:13:41 -07004241 except Exception:
4242 main.log.exception( self.name + ": Uncaught exception!" )
4243 main.cleanup()
4244 main.exit()
4245
Jon Hall80daded2015-05-27 16:07:00 -07004246 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004247 """
4248 Command to list the various counters in the system.
4249 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004250 if jsonFormat, a string of the json object returned by the cli
4251 command
4252 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004253 None on error
4254 """
Jon Hall390696c2015-05-05 17:13:41 -07004255 try:
4256 counters = {}
4257 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004258 if jsonFormat:
4259 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004260 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004261 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004262 assert "Command not found:" not in output, output
4263 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004264 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004265 return output
Jon Hall390696c2015-05-05 17:13:41 -07004266 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004267 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004268 return None
Jon Hall390696c2015-05-05 17:13:41 -07004269 except TypeError:
4270 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004271 return None
Jon Hall390696c2015-05-05 17:13:41 -07004272 except pexpect.EOF:
4273 main.log.error( self.name + ": EOF exception found" )
4274 main.log.error( self.name + ": " + self.handle.before )
4275 main.cleanup()
4276 main.exit()
4277 except Exception:
4278 main.log.exception( self.name + ": Uncaught exception!" )
4279 main.cleanup()
4280 main.exit()
4281
Jon Hall935db192016-04-19 00:22:04 -07004282 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004283 """
Jon Halle1a3b752015-07-22 13:02:46 -07004284 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004285 Required arguments:
4286 counter - The name of the counter to increment.
4287 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004288 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004289 returns:
4290 integer value of the counter or
4291 None on Error
4292 """
4293 try:
4294 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004295 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004296 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004297 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004298 if delta != 1:
4299 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004300 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004301 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004302 match = re.search( pattern, output )
4303 if match:
4304 return int( match.group( 1 ) )
4305 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004306 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004307 " match expected output." )
4308 main.log.debug( self.name + " expected: " + pattern )
4309 main.log.debug( self.name + " actual: " + repr( output ) )
4310 return None
Jon Hall390696c2015-05-05 17:13:41 -07004311 except TypeError:
4312 main.log.exception( self.name + ": Object not as expected" )
4313 return None
Jon Hall390696c2015-05-05 17:13:41 -07004314 except Exception:
4315 main.log.exception( self.name + ": Uncaught exception!" )
4316 main.cleanup()
4317 main.exit()
4318
Jon Hall935db192016-04-19 00:22:04 -07004319 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004320 """
4321 CLI command to get a distributed counter then add a delta to it.
4322 Required arguments:
4323 counter - The name of the counter to increment.
4324 Optional arguments:
4325 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004326 returns:
4327 integer value of the counter or
4328 None on Error
4329 """
4330 try:
4331 counter = str( counter )
4332 delta = int( delta )
4333 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004334 cmdStr += counter
4335 if delta != 1:
4336 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004337 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004338 pattern = counter + " was updated to (-?\d+)"
4339 match = re.search( pattern, output )
4340 if match:
4341 return int( match.group( 1 ) )
4342 else:
4343 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4344 " match expected output." )
4345 main.log.debug( self.name + " expected: " + pattern )
4346 main.log.debug( self.name + " actual: " + repr( output ) )
4347 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004348 except TypeError:
4349 main.log.exception( self.name + ": Object not as expected" )
4350 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004351 except Exception:
4352 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004353 main.cleanup()
4354 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004355
4356 def valueTestGet( self, valueName ):
4357 """
4358 CLI command to get the value of an atomic value.
4359 Required arguments:
4360 valueName - The name of the value to get.
4361 returns:
4362 string value of the value or
4363 None on Error
4364 """
4365 try:
4366 valueName = str( valueName )
4367 cmdStr = "value-test "
4368 operation = "get"
4369 cmdStr = "value-test {} {}".format( valueName,
4370 operation )
4371 output = self.distPrimitivesSend( cmdStr )
4372 pattern = "(\w+)"
4373 match = re.search( pattern, output )
4374 if match:
4375 return match.group( 1 )
4376 else:
4377 main.log.error( self.name + ": valueTestGet did not" +
4378 " match expected output." )
4379 main.log.debug( self.name + " expected: " + pattern )
4380 main.log.debug( self.name + " actual: " + repr( output ) )
4381 return None
4382 except TypeError:
4383 main.log.exception( self.name + ": Object not as expected" )
4384 return None
4385 except Exception:
4386 main.log.exception( self.name + ": Uncaught exception!" )
4387 main.cleanup()
4388 main.exit()
4389
4390 def valueTestSet( self, valueName, newValue ):
4391 """
4392 CLI command to set the value of an atomic value.
4393 Required arguments:
4394 valueName - The name of the value to set.
4395 newValue - The value to assign to the given value.
4396 returns:
4397 main.TRUE on success or
4398 main.ERROR on Error
4399 """
4400 try:
4401 valueName = str( valueName )
4402 newValue = str( newValue )
4403 operation = "set"
4404 cmdStr = "value-test {} {} {}".format( valueName,
4405 operation,
4406 newValue )
4407 output = self.distPrimitivesSend( cmdStr )
4408 if output is not None:
4409 return main.TRUE
4410 else:
4411 return main.ERROR
4412 except TypeError:
4413 main.log.exception( self.name + ": Object not as expected" )
4414 return main.ERROR
4415 except Exception:
4416 main.log.exception( self.name + ": Uncaught exception!" )
4417 main.cleanup()
4418 main.exit()
4419
4420 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4421 """
4422 CLI command to compareAndSet the value of an atomic value.
4423 Required arguments:
4424 valueName - The name of the value.
4425 oldValue - Compare the current value of the atomic value to this
4426 newValue - If the value equals oldValue, set the value to newValue
4427 returns:
4428 main.TRUE on success or
4429 main.FALSE on failure or
4430 main.ERROR on Error
4431 """
4432 try:
4433 valueName = str( valueName )
4434 oldValue = str( oldValue )
4435 newValue = str( newValue )
4436 operation = "compareAndSet"
4437 cmdStr = "value-test {} {} {} {}".format( valueName,
4438 operation,
4439 oldValue,
4440 newValue )
4441 output = self.distPrimitivesSend( cmdStr )
4442 pattern = "(\w+)"
4443 match = re.search( pattern, output )
4444 if match:
4445 result = match.group( 1 )
4446 if result == "true":
4447 return main.TRUE
4448 elif result == "false":
4449 return main.FALSE
4450 else:
4451 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4452 " match expected output." )
4453 main.log.debug( self.name + " expected: " + pattern )
4454 main.log.debug( self.name + " actual: " + repr( output ) )
4455 return main.ERROR
4456 except TypeError:
4457 main.log.exception( self.name + ": Object not as expected" )
4458 return main.ERROR
4459 except Exception:
4460 main.log.exception( self.name + ": Uncaught exception!" )
4461 main.cleanup()
4462 main.exit()
4463
4464 def valueTestGetAndSet( self, valueName, newValue ):
4465 """
4466 CLI command to getAndSet the value of an atomic value.
4467 Required arguments:
4468 valueName - The name of the value to get.
4469 newValue - The value to assign to the given value
4470 returns:
4471 string value of the value or
4472 None on Error
4473 """
4474 try:
4475 valueName = str( valueName )
4476 cmdStr = "value-test "
4477 operation = "getAndSet"
4478 cmdStr += valueName + " " + operation
4479 cmdStr = "value-test {} {} {}".format( valueName,
4480 operation,
4481 newValue )
4482 output = self.distPrimitivesSend( cmdStr )
4483 pattern = "(\w+)"
4484 match = re.search( pattern, output )
4485 if match:
4486 return match.group( 1 )
4487 else:
4488 main.log.error( self.name + ": valueTestGetAndSet did not" +
4489 " match expected output." )
4490 main.log.debug( self.name + " expected: " + pattern )
4491 main.log.debug( self.name + " actual: " + repr( output ) )
4492 return None
4493 except TypeError:
4494 main.log.exception( self.name + ": Object not as expected" )
4495 return None
4496 except Exception:
4497 main.log.exception( self.name + ": Uncaught exception!" )
4498 main.cleanup()
4499 main.exit()
4500
4501 def valueTestDestroy( self, valueName ):
4502 """
4503 CLI command to destroy an atomic value.
4504 Required arguments:
4505 valueName - The name of the value to destroy.
4506 returns:
4507 main.TRUE on success or
4508 main.ERROR on Error
4509 """
4510 try:
4511 valueName = str( valueName )
4512 cmdStr = "value-test "
4513 operation = "destroy"
4514 cmdStr += valueName + " " + operation
4515 output = self.distPrimitivesSend( cmdStr )
4516 if output is not None:
4517 return main.TRUE
4518 else:
4519 return main.ERROR
4520 except TypeError:
4521 main.log.exception( self.name + ": Object not as expected" )
4522 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004523 except Exception:
4524 main.log.exception( self.name + ": Uncaught exception!" )
4525 main.cleanup()
4526 main.exit()
4527
YPZhangfebf7302016-05-24 16:45:56 -07004528 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004529 """
4530 Description: Execute summary command in onos
4531 Returns: json object ( summary -j ), returns main.FALSE if there is
4532 no output
4533
4534 """
4535 try:
4536 cmdStr = "summary"
4537 if jsonFormat:
4538 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004539 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004540 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004541 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004542 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004543 if not handle:
4544 main.log.error( self.name + ": There is no output in " +
4545 "summary command" )
4546 return main.FALSE
4547 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004548 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004549 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004550 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004551 except TypeError:
4552 main.log.exception( self.name + ": Object not as expected" )
4553 return None
4554 except pexpect.EOF:
4555 main.log.error( self.name + ": EOF exception found" )
4556 main.log.error( self.name + ": " + self.handle.before )
4557 main.cleanup()
4558 main.exit()
4559 except Exception:
4560 main.log.exception( self.name + ": Uncaught exception!" )
4561 main.cleanup()
4562 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004563
Jon Hall935db192016-04-19 00:22:04 -07004564 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004565 """
4566 CLI command to get the value of a key in a consistent map using
4567 transactions. This a test function and can only get keys from the
4568 test map hard coded into the cli command
4569 Required arguments:
4570 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004571 returns:
4572 The string value of the key or
4573 None on Error
4574 """
4575 try:
4576 keyName = str( keyName )
4577 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004579 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004580 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4581 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004582 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004583 return None
4584 else:
4585 match = re.search( pattern, output )
4586 if match:
4587 return match.groupdict()[ 'value' ]
4588 else:
4589 main.log.error( self.name + ": transactionlMapGet did not" +
4590 " match expected output." )
4591 main.log.debug( self.name + " expected: " + pattern )
4592 main.log.debug( self.name + " actual: " + repr( output ) )
4593 return None
4594 except TypeError:
4595 main.log.exception( self.name + ": Object not as expected" )
4596 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004597 except Exception:
4598 main.log.exception( self.name + ": Uncaught exception!" )
4599 main.cleanup()
4600 main.exit()
4601
Jon Hall935db192016-04-19 00:22:04 -07004602 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004603 """
4604 CLI command to put a value into 'numKeys' number of keys in a
4605 consistent map using transactions. This a test function and can only
4606 put into keys named 'Key#' of the test map hard coded into the cli command
4607 Required arguments:
4608 numKeys - Number of keys to add the value to
4609 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004610 returns:
4611 A dictionary whose keys are the name of the keys put into the map
4612 and the values of the keys are dictionaries whose key-values are
4613 'value': value put into map and optionaly
4614 'oldValue': Previous value in the key or
4615 None on Error
4616
4617 Example output
4618 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4619 'Key2': {'value': 'Testing'} }
4620 """
4621 try:
4622 numKeys = str( numKeys )
4623 value = str( value )
4624 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004625 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004626 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004627 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4628 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4629 results = {}
4630 for line in output.splitlines():
4631 new = re.search( newPattern, line )
4632 updated = re.search( updatedPattern, line )
4633 if new:
4634 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4635 elif updated:
4636 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004637 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004638 else:
4639 main.log.error( self.name + ": transactionlMapGet did not" +
4640 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004641 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4642 newPattern,
4643 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004644 main.log.debug( self.name + " actual: " + repr( output ) )
4645 return results
4646 except TypeError:
4647 main.log.exception( self.name + ": Object not as expected" )
4648 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004649 except Exception:
4650 main.log.exception( self.name + ": Uncaught exception!" )
4651 main.cleanup()
4652 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004653
acsmarsdaea66c2015-09-03 11:44:06 -07004654 def maps( self, jsonFormat=True ):
4655 """
4656 Description: Returns result of onos:maps
4657 Optional:
4658 * jsonFormat: enable json formatting of output
4659 """
4660 try:
4661 cmdStr = "maps"
4662 if jsonFormat:
4663 cmdStr += " -j"
4664 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004665 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004666 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004667 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004668 except AssertionError:
4669 main.log.exception( "" )
4670 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004671 except TypeError:
4672 main.log.exception( self.name + ": Object not as expected" )
4673 return None
4674 except pexpect.EOF:
4675 main.log.error( self.name + ": EOF exception found" )
4676 main.log.error( self.name + ": " + self.handle.before )
4677 main.cleanup()
4678 main.exit()
4679 except Exception:
4680 main.log.exception( self.name + ": Uncaught exception!" )
4681 main.cleanup()
4682 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004683
4684 def getSwController( self, uri, jsonFormat=True ):
4685 """
4686 Descrition: Gets the controller information from the device
4687 """
4688 try:
4689 cmd = "device-controllers "
4690 if jsonFormat:
4691 cmd += "-j "
4692 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004693 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004694 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004695 return response
Jon Hallc6793552016-01-19 14:18:37 -08004696 except AssertionError:
4697 main.log.exception( "" )
4698 return None
GlennRC050596c2015-11-18 17:06:41 -08004699 except TypeError:
4700 main.log.exception( self.name + ": Object not as expected" )
4701 return None
4702 except pexpect.EOF:
4703 main.log.error( self.name + ": EOF exception found" )
4704 main.log.error( self.name + ": " + self.handle.before )
4705 main.cleanup()
4706 main.exit()
4707 except Exception:
4708 main.log.exception( self.name + ": Uncaught exception!" )
4709 main.cleanup()
4710 main.exit()
4711
4712 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4713 """
4714 Descrition: sets the controller(s) for the specified device
4715
4716 Parameters:
4717 Required: uri - String: The uri of the device(switch).
4718 ip - String or List: The ip address of the controller.
4719 This parameter can be formed in a couple of different ways.
4720 VALID:
4721 10.0.0.1 - just the ip address
4722 tcp:10.0.0.1 - the protocol and the ip address
4723 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4724 so that you can add controllers with different
4725 protocols and ports
4726 INVALID:
4727 10.0.0.1:6653 - this is not supported by ONOS
4728
4729 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4730 port - The port number.
4731 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4732
4733 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4734 """
4735 try:
4736 cmd = "device-setcontrollers"
4737
4738 if jsonFormat:
4739 cmd += " -j"
4740 cmd += " " + uri
4741 if isinstance( ip, str ):
4742 ip = [ip]
4743 for item in ip:
4744 if ":" in item:
4745 sitem = item.split( ":" )
4746 if len(sitem) == 3:
4747 cmd += " " + item
4748 elif "." in sitem[1]:
4749 cmd += " {}:{}".format(item, port)
4750 else:
4751 main.log.error( "Malformed entry: " + item )
4752 raise TypeError
4753 else:
4754 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004755 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004756 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004757 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004758 if "Error" in response:
4759 main.log.error( response )
4760 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004761 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004762 except AssertionError:
4763 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004764 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004765 except TypeError:
4766 main.log.exception( self.name + ": Object not as expected" )
4767 return main.FALSE
4768 except pexpect.EOF:
4769 main.log.error( self.name + ": EOF exception found" )
4770 main.log.error( self.name + ": " + self.handle.before )
4771 main.cleanup()
4772 main.exit()
4773 except Exception:
4774 main.log.exception( self.name + ": Uncaught exception!" )
4775 main.cleanup()
4776 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004777
4778 def removeDevice( self, device ):
4779 '''
4780 Description:
4781 Remove a device from ONOS by passing the uri of the device(s).
4782 Parameters:
4783 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4784 Returns:
4785 Returns main.FALSE if an exception is thrown or an error is present
4786 in the response. Otherwise, returns main.TRUE.
4787 NOTE:
4788 If a host cannot be removed, then this function will return main.FALSE
4789 '''
4790 try:
4791 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004792 deviceStr = device
4793 device = []
4794 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004795
4796 for d in device:
4797 time.sleep( 1 )
4798 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004799 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004800 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004801 if "Error" in response:
4802 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4803 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004804 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004805 except AssertionError:
4806 main.log.exception( "" )
4807 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004808 except TypeError:
4809 main.log.exception( self.name + ": Object not as expected" )
4810 return main.FALSE
4811 except pexpect.EOF:
4812 main.log.error( self.name + ": EOF exception found" )
4813 main.log.error( self.name + ": " + self.handle.before )
4814 main.cleanup()
4815 main.exit()
4816 except Exception:
4817 main.log.exception( self.name + ": Uncaught exception!" )
4818 main.cleanup()
4819 main.exit()
4820
4821 def removeHost( self, host ):
4822 '''
4823 Description:
4824 Remove a host from ONOS by passing the id of the host(s)
4825 Parameters:
4826 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4827 Returns:
4828 Returns main.FALSE if an exception is thrown or an error is present
4829 in the response. Otherwise, returns main.TRUE.
4830 NOTE:
4831 If a host cannot be removed, then this function will return main.FALSE
4832 '''
4833 try:
4834 if type( host ) is str:
4835 host = list( host )
4836
4837 for h in host:
4838 time.sleep( 1 )
4839 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004840 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004841 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004842 if "Error" in response:
4843 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4844 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004845 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004846 except AssertionError:
4847 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004848 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004849 except TypeError:
4850 main.log.exception( self.name + ": Object not as expected" )
4851 return main.FALSE
4852 except pexpect.EOF:
4853 main.log.error( self.name + ": EOF exception found" )
4854 main.log.error( self.name + ": " + self.handle.before )
4855 main.cleanup()
4856 main.exit()
4857 except Exception:
4858 main.log.exception( self.name + ": Uncaught exception!" )
4859 main.cleanup()
4860 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004861
YPZhangfebf7302016-05-24 16:45:56 -07004862 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004863 '''
4864 Description:
4865 Bring link down or up in the null-provider.
4866 params:
4867 begin - (string) One end of a device or switch.
4868 end - (string) the other end of the device or switch
4869 returns:
4870 main.TRUE if no exceptions were thrown and no Errors are
4871 present in the resoponse. Otherwise, returns main.FALSE
4872 '''
4873 try:
Jon Hallc6793552016-01-19 14:18:37 -08004874 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004875 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004876 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004877 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004878 if "Error" in response or "Failure" in response:
4879 main.log.error( response )
4880 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004881 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004882 except AssertionError:
4883 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004884 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004885 except TypeError:
4886 main.log.exception( self.name + ": Object not as expected" )
4887 return main.FALSE
4888 except pexpect.EOF:
4889 main.log.error( self.name + ": EOF exception found" )
4890 main.log.error( self.name + ": " + self.handle.before )
4891 main.cleanup()
4892 main.exit()
4893 except Exception:
4894 main.log.exception( self.name + ": Uncaught exception!" )
4895 main.cleanup()
4896 main.exit()
4897
Jon Hall2c8959e2016-12-16 12:17:34 -08004898 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004899 '''
4900 Description:
4901 Changes the state of port in an OF switch by means of the
4902 PORTSTATUS OF messages.
4903 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004904 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4905 port - (string) target port in the device. Ex: '2'
4906 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004907 returns:
4908 main.TRUE if no exceptions were thrown and no Errors are
4909 present in the resoponse. Otherwise, returns main.FALSE
4910 '''
4911 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004912 state = state.lower()
4913 assert state == 'enable' or state == 'disable', "Unknown state"
Flavio Castro82ee2f62016-06-07 15:04:12 -07004914 cmd = "portstate {} {} {}".format( dpid, port, state )
4915 response = self.sendline( cmd, showResponse=True )
4916 assert response is not None, "Error in sendline"
4917 assert "Command not found:" not in response, response
4918 if "Error" in response or "Failure" in response:
4919 main.log.error( response )
4920 return main.FALSE
4921 return main.TRUE
4922 except AssertionError:
4923 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004924 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004925 except TypeError:
4926 main.log.exception( self.name + ": Object not as expected" )
4927 return main.FALSE
4928 except pexpect.EOF:
4929 main.log.error( self.name + ": EOF exception found" )
4930 main.log.error( self.name + ": " + self.handle.before )
4931 main.cleanup()
4932 main.exit()
4933 except Exception:
4934 main.log.exception( self.name + ": Uncaught exception!" )
4935 main.cleanup()
4936 main.exit()
4937
4938 def logSet( self, level="INFO", app="org.onosproject" ):
4939 """
4940 Set the logging level to lvl for a specific app
4941 returns main.TRUE on success
4942 returns main.FALSE if Error occurred
4943 if noExit is True, TestON will not exit, but clean up
4944 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4945 Level defaults to INFO
4946 """
4947 try:
4948 self.handle.sendline( "log:set %s %s" %( level, app ) )
4949 self.handle.expect( "onos>" )
4950
4951 response = self.handle.before
4952 if re.search( "Error", response ):
4953 return main.FALSE
4954 return main.TRUE
4955 except pexpect.TIMEOUT:
4956 main.log.exception( self.name + ": TIMEOUT exception found" )
4957 main.cleanup()
4958 main.exit()
4959 except pexpect.EOF:
4960 main.log.error( self.name + ": EOF exception found" )
4961 main.log.error( self.name + ": " + self.handle.before )
4962 main.cleanup()
4963 main.exit()
4964 except Exception:
4965 main.log.exception( self.name + ": Uncaught exception!" )
4966 main.cleanup()
4967 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004968
4969 def getGraphDict( self, timeout=60, includeHost=False ):
4970 """
4971 Return a dictionary which describes the latest network topology data as a
4972 graph.
4973 An example of the dictionary:
4974 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4975 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4976 Each vertex should at least have an 'edges' attribute which describes the
4977 adjacency information. The value of 'edges' attribute is also represented by
4978 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4979 list of attributes.
4980 An example of the edges dictionary:
4981 'edges': { vertex2: { 'port': ..., 'weight': ... },
4982 vertex3: { 'port': ..., 'weight': ... } }
4983 If includeHost == True, all hosts (and host-switch links) will be included
4984 in topology data.
4985 """
4986 graphDict = {}
4987 try:
4988 links = self.links()
4989 links = json.loads( links )
4990 devices = self.devices()
4991 devices = json.loads( devices )
4992 idToDevice = {}
4993 for device in devices:
4994 idToDevice[ device[ 'id' ] ] = device
4995 if includeHost:
4996 hosts = self.hosts()
4997 # FIXME: support 'includeHost' argument
4998 for link in links:
4999 nodeA = link[ 'src' ][ 'device' ]
5000 nodeB = link[ 'dst' ][ 'device' ]
5001 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
5002 if not nodeA in graphDict.keys():
5003 graphDict[ nodeA ] = { 'edges':{},
5004 'dpid':idToDevice[ nodeA ][ 'id' ][3:],
5005 'type':idToDevice[ nodeA ][ 'type' ],
5006 'available':idToDevice[ nodeA ][ 'available' ],
5007 'role':idToDevice[ nodeA ][ 'role' ],
5008 'mfr':idToDevice[ nodeA ][ 'mfr' ],
5009 'hw':idToDevice[ nodeA ][ 'hw' ],
5010 'sw':idToDevice[ nodeA ][ 'sw' ],
5011 'serial':idToDevice[ nodeA ][ 'serial' ],
5012 'chassisId':idToDevice[ nodeA ][ 'chassisId' ],
5013 'annotations':idToDevice[ nodeA ][ 'annotations' ]}
5014 else:
5015 # Assert nodeB is not connected to any current links of nodeA
5016 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5017 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port':link[ 'src' ][ 'port' ],
5018 'type':link[ 'type' ],
5019 'state':link[ 'state' ] }
5020 return graphDict
5021 except ( TypeError, ValueError ):
5022 main.log.exception( self.name + ": Object not as expected" )
5023 return None
5024 except KeyError:
5025 main.log.exception( self.name + ": KeyError exception found" )
5026 return None
5027 except AssertionError:
5028 main.log.exception( self.name + ": AssertionError exception found" )
5029 return None
5030 except pexpect.EOF:
5031 main.log.error( self.name + ": EOF exception found" )
5032 main.log.error( self.name + ": " + self.handle.before )
5033 return None
5034 except Exception:
5035 main.log.exception( self.name + ": Uncaught exception!" )
5036 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005037
5038 def getIntentPerfSummary( self ):
5039 '''
5040 Send command to check intent-perf summary
5041 Returns: dictionary for intent-perf summary
5042 if something wrong, function will return None
5043 '''
5044 cmd = "intent-perf -s"
5045 respDic = {}
5046 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005047 assert resp is not None, "Error in sendline"
5048 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005049 try:
5050 # Generate the dictionary to return
5051 for l in resp.split( "\n" ):
5052 # Delete any white space in line
5053 temp = re.sub( r'\s+', '', l )
5054 temp = temp.split( ":" )
5055 respDic[ temp[0] ] = temp[ 1 ]
5056
5057 except (TypeError, ValueError):
5058 main.log.exception( self.name + ": Object not as expected" )
5059 return None
5060 except KeyError:
5061 main.log.exception( self.name + ": KeyError exception found" )
5062 return None
5063 except AssertionError:
5064 main.log.exception( self.name + ": AssertionError exception found" )
5065 return None
5066 except pexpect.EOF:
5067 main.log.error( self.name + ": EOF exception found" )
5068 main.log.error( self.name + ": " + self.handle.before )
5069 return None
5070 except Exception:
5071 main.log.exception( self.name + ": Uncaught exception!" )
5072 return None
5073 return respDic
5074
Chiyu Chengec63bde2016-11-17 18:11:36 -08005075 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005076 """
5077 Searches the latest ONOS log file for the given search term and
5078 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005079
chengchiyu08303a02016-09-08 17:40:26 -07005080 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005081 searchTerm:
5082 The string to grep from the ONOS log.
5083 startLine:
5084 The term that decides which line is the start to search the searchTerm in
5085 the karaf log. For now, startTerm only works in 'first' mode.
5086 logNum:
5087 In some extreme cases, one karaf log is not big enough to contain all the
5088 information.Because of this, search mutiply logs is necessary to capture
5089 the right result. logNum is the number of karaf logs that we need to search
5090 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005091 mode:
5092 all: return all the strings that contain the search term
5093 last: return the last string that contains the search term
5094 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005095 num: return the number of times that the searchTerm appears in the log
5096 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005097 """
5098 try:
5099 assert type( searchTerm ) is str
Chiyu Chengec63bde2016-11-17 18:11:36 -08005100 #Build the log paths string
5101 logPath = '/opt/onos/log/karaf.log.'
5102 logPaths = '/opt/onos/log/karaf.log'
5103 for i in range( 1, logNum ):
5104 logPaths = logPath + str( i ) + " " + logPaths
5105 cmd = "cat " + logPaths
5106 if mode == 'all':
5107 cmd = cmd + " | grep \'" + searchTerm + "\'"
chengchiyu08303a02016-09-08 17:40:26 -07005108 if mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005109 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
chengchiyu08303a02016-09-08 17:40:26 -07005110 if mode == 'first':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005111 if startLine != '':
5112 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5113 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\' | grep \'" + searchTerm + "\'" + "| head -n 1"
5114 else:
5115 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005116 if mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005117 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005118 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005119 return num
Chiyu Chengec63bde2016-11-17 18:11:36 -08005120 if mode == 'total':
5121 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5122 return int(totalLines)
chengchiyu08303a02016-09-08 17:40:26 -07005123 before = self.sendline( cmd )
5124 before = before.splitlines()
5125 # make sure the returned list only contains the search term
5126 returnLines = [line for line in before if searchTerm in line]
5127 return returnLines
5128 except AssertionError:
5129 main.log.error( self.name + " searchTerm is not string type" )
5130 return None
5131 except pexpect.EOF:
5132 main.log.error( self.name + ": EOF exception found" )
5133 main.log.error( self.name + ": " + self.handle.before )
5134 main.cleanup()
5135 main.exit()
5136 except pexpect.TIMEOUT:
5137 main.log.error( self.name + ": TIMEOUT exception found" )
5138 main.log.error( self.name + ": " + self.handle.before )
5139 main.cleanup()
5140 main.exit()
5141 except Exception:
5142 main.log.exception( self.name + ": Uncaught exception!" )
5143 main.cleanup()
5144 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005145
5146 def vplsShow( self, jsonFormat=True ):
5147 """
5148 Description: Returns result of onos:vpls show, which should list the
5149 configured VPLS networks and the assigned interfaces.
5150 Optional:
5151 * jsonFormat: enable json formatting of output
5152 Returns:
5153 The output of the command or None on error.
5154 """
5155 try:
5156 cmdStr = "vpls show"
5157 if jsonFormat:
5158 raise NotImplementedError
5159 cmdStr += " -j"
5160 handle = self.sendline( cmdStr )
5161 assert handle is not None, "Error in sendline"
5162 assert "Command not found:" not in handle, handle
5163 return handle
5164 except AssertionError:
5165 main.log.exception( "" )
5166 return None
5167 except TypeError:
5168 main.log.exception( self.name + ": Object not as expected" )
5169 return None
5170 except pexpect.EOF:
5171 main.log.error( self.name + ": EOF exception found" )
5172 main.log.error( self.name + ": " + self.handle.before )
5173 main.cleanup()
5174 main.exit()
5175 except NotImplementedError:
5176 main.log.exception( self.name + ": Json output not supported")
5177 return None
5178 except Exception:
5179 main.log.exception( self.name + ": Uncaught exception!" )
5180 main.cleanup()
5181 main.exit()
5182
5183 def parseVplsShow( self ):
5184 """
5185 Parse the cli output of 'vpls show' into json output. This is required
5186 as there is currently no json output available.
5187 """
5188 try:
5189 output = []
5190 raw = self.vplsShow( jsonFormat=False )
5191 namePat = "VPLS name: (?P<name>\w+)"
5192 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5193 encapPat = "Encapsulation: (?P<encap>\w+)"
5194 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5195 mIter = re.finditer( pattern, raw )
5196 for match in mIter:
5197 item = {}
5198 item[ 'name' ] = match.group( 'name' )
5199 ifaces = match.group( 'interfaces' ).split( ', ')
5200 if ifaces == [ "" ]:
5201 ifaces = []
5202 item[ 'interfaces' ] = ifaces
5203 encap = match.group( 'encap' )
5204 if encap != 'NONE':
5205 item[ 'encapsulation' ] = encap.lower()
5206 output.append( item )
5207 return output
5208 except Exception:
5209 main.log.exception( self.name + ": Uncaught exception!" )
5210 main.cleanup()
5211 main.exit()
5212
5213 def vplsList( self, jsonFormat=True ):
5214 """
5215 Description: Returns result of onos:vpls list, which should list the
5216 configured VPLS networks.
5217 Optional:
5218 * jsonFormat: enable json formatting of output
5219 """
5220 try:
5221 cmdStr = "vpls list"
5222 if jsonFormat:
5223 raise NotImplementedError
5224 cmdStr += " -j"
5225 handle = self.sendline( cmdStr )
5226 assert handle is not None, "Error in sendline"
5227 assert "Command not found:" not in handle, handle
5228 return handle
5229 except AssertionError:
5230 main.log.exception( "" )
5231 return None
5232 except TypeError:
5233 main.log.exception( self.name + ": Object not as expected" )
5234 return None
5235 except pexpect.EOF:
5236 main.log.error( self.name + ": EOF exception found" )
5237 main.log.error( self.name + ": " + self.handle.before )
5238 main.cleanup()
5239 main.exit()
5240 except NotImplementedError:
5241 main.log.exception( self.name + ": Json output not supported")
5242 return None
5243 except Exception:
5244 main.log.exception( self.name + ": Uncaught exception!" )
5245 main.cleanup()
5246 main.exit()
5247
5248 def vplsCreate( self, network ):
5249 """
5250 CLI command to create a new VPLS network.
5251 Required arguments:
5252 network - String name of the network to create.
5253 returns:
5254 main.TRUE on success and main.FALSE on failure
5255 """
5256 try:
5257 network = str( network )
5258 cmdStr = "vpls create "
5259 cmdStr += network
5260 output = self.sendline( cmdStr )
5261 assert output is not None, "Error in sendline"
5262 assert "Command not found:" not in output, output
5263 assert "Error executing command" not in output, output
5264 assert "VPLS already exists:" not in output, output
5265 return main.TRUE
5266 except AssertionError:
5267 main.log.exception( "" )
5268 return main.FALSE
5269 except TypeError:
5270 main.log.exception( self.name + ": Object not as expected" )
5271 return main.FALSE
5272 except pexpect.EOF:
5273 main.log.error( self.name + ": EOF exception found" )
5274 main.log.error( self.name + ": " + self.handle.before )
5275 main.cleanup()
5276 main.exit()
5277 except Exception:
5278 main.log.exception( self.name + ": Uncaught exception!" )
5279 main.cleanup()
5280 main.exit()
5281
5282 def vplsDelete( self, network ):
5283 """
5284 CLI command to delete a VPLS network.
5285 Required arguments:
5286 network - Name of the network to delete.
5287 returns:
5288 main.TRUE on success and main.FALSE on failure
5289 """
5290 try:
5291 network = str( network )
5292 cmdStr = "vpls delete "
5293 cmdStr += network
5294 output = self.sendline( cmdStr )
5295 assert output is not None, "Error in sendline"
5296 assert "Command not found:" not in output, output
5297 assert "Error executing command" not in output, output
5298 assert " not found" not in output, output
5299 return main.TRUE
5300 except AssertionError:
5301 main.log.exception( "" )
5302 return main.FALSE
5303 except TypeError:
5304 main.log.exception( self.name + ": Object not as expected" )
5305 return main.FALSE
5306 except pexpect.EOF:
5307 main.log.error( self.name + ": EOF exception found" )
5308 main.log.error( self.name + ": " + self.handle.before )
5309 main.cleanup()
5310 main.exit()
5311 except Exception:
5312 main.log.exception( self.name + ": Uncaught exception!" )
5313 main.cleanup()
5314 main.exit()
5315
5316 def vplsAddIface( self, network, iface ):
5317 """
5318 CLI command to add an interface to a VPLS network.
5319 Required arguments:
5320 network - Name of the network to add the interface to.
5321 iface - The ONOS name for an interface.
5322 returns:
5323 main.TRUE on success and main.FALSE on failure
5324 """
5325 try:
5326 network = str( network )
5327 iface = str( iface )
5328 cmdStr = "vpls add-if "
5329 cmdStr += network + " " + iface
5330 output = self.sendline( cmdStr )
5331 assert output is not None, "Error in sendline"
5332 assert "Command not found:" not in output, output
5333 assert "Error executing command" not in output, output
5334 assert "already associated to network" not in output, output
5335 assert "Interface cannot be added." not in output, output
5336 return main.TRUE
5337 except AssertionError:
5338 main.log.exception( "" )
5339 return main.FALSE
5340 except TypeError:
5341 main.log.exception( self.name + ": Object not as expected" )
5342 return main.FALSE
5343 except pexpect.EOF:
5344 main.log.error( self.name + ": EOF exception found" )
5345 main.log.error( self.name + ": " + self.handle.before )
5346 main.cleanup()
5347 main.exit()
5348 except Exception:
5349 main.log.exception( self.name + ": Uncaught exception!" )
5350 main.cleanup()
5351 main.exit()
5352
5353 def vplsRemIface( self, network, iface ):
5354 """
5355 CLI command to remove an interface from a VPLS network.
5356 Required arguments:
5357 network - Name of the network to remove the interface from.
5358 iface - Name of the interface to remove.
5359 returns:
5360 main.TRUE on success and main.FALSE on failure
5361 """
5362 try:
5363 iface = str( iface )
5364 cmdStr = "vpls rem-if "
5365 cmdStr += network + " " + iface
5366 output = self.sendline( cmdStr )
5367 assert output is not None, "Error in sendline"
5368 assert "Command not found:" not in output, output
5369 assert "Error executing command" not in output, output
5370 assert "is not configured" not in output, output
5371 return main.TRUE
5372 except AssertionError:
5373 main.log.exception( "" )
5374 return main.FALSE
5375 except TypeError:
5376 main.log.exception( self.name + ": Object not as expected" )
5377 return main.FALSE
5378 except pexpect.EOF:
5379 main.log.error( self.name + ": EOF exception found" )
5380 main.log.error( self.name + ": " + self.handle.before )
5381 main.cleanup()
5382 main.exit()
5383 except Exception:
5384 main.log.exception( self.name + ": Uncaught exception!" )
5385 main.cleanup()
5386 main.exit()
5387
5388 def vplsClean( self ):
5389 """
5390 Description: Clears the VPLS app configuration.
5391 Returns: main.TRUE on success and main.FALSE on failure
5392 """
5393 try:
5394 cmdStr = "vpls clean"
5395 handle = self.sendline( cmdStr )
5396 assert handle is not None, "Error in sendline"
5397 assert "Command not found:" not in handle, handle
5398 return handle
5399 except AssertionError:
5400 main.log.exception( "" )
5401 return main.FALSE
5402 except TypeError:
5403 main.log.exception( self.name + ": Object not as expected" )
5404 return main.FALSE
5405 except pexpect.EOF:
5406 main.log.error( self.name + ": EOF exception found" )
5407 main.log.error( self.name + ": " + self.handle.before )
5408 main.cleanup()
5409 main.exit()
5410 except Exception:
5411 main.log.exception( self.name + ": Uncaught exception!" )
5412 main.cleanup()
5413 main.exit()
5414
5415 def vplsSetEncap( self, network, encapType ):
5416 """
5417 CLI command to add an interface to a VPLS network.
5418 Required arguments:
5419 network - Name of the network to create.
5420 encapType - Type of encapsulation.
5421 returns:
5422 main.TRUE on success and main.FALSE on failure
5423 """
5424 try:
5425 network = str( network )
5426 encapType = str( encapType ).upper()
5427 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5428 cmdStr = "vpls set-encap "
5429 cmdStr += network + " " + encapType
5430 output = self.sendline( cmdStr )
5431 assert output is not None, "Error in sendline"
5432 assert "Command not found:" not in output, output
5433 assert "Error executing command" not in output, output
5434 assert "already associated to network" not in output, output
5435 assert "Encapsulation type " not in output, output
5436 return main.TRUE
5437 except AssertionError:
5438 main.log.exception( "" )
5439 return main.FALSE
5440 except TypeError:
5441 main.log.exception( self.name + ": Object not as expected" )
5442 return main.FALSE
5443 except pexpect.EOF:
5444 main.log.error( self.name + ": EOF exception found" )
5445 main.log.error( self.name + ": " + self.handle.before )
5446 main.cleanup()
5447 main.exit()
5448 except Exception:
5449 main.log.exception( self.name + ": Uncaught exception!" )
5450 main.cleanup()
5451 main.exit()
5452
5453 def interfaces( self, jsonFormat=True ):
5454 """
5455 Description: Returns result of interfaces command.
5456 Optional:
5457 * jsonFormat: enable json formatting of output
5458 Returns:
5459 The output of the command or None on error.
5460 """
5461 try:
5462 cmdStr = "interfaces"
5463 if jsonFormat:
5464 #raise NotImplementedError
5465 cmdStr += " -j"
5466 handle = self.sendline( cmdStr )
5467 assert handle is not None, "Error in sendline"
5468 assert "Command not found:" not in handle, handle
5469 return handle
5470 except AssertionError:
5471 main.log.exception( "" )
5472 return None
5473 except TypeError:
5474 main.log.exception( self.name + ": Object not as expected" )
5475 return None
5476 except pexpect.EOF:
5477 main.log.error( self.name + ": EOF exception found" )
5478 main.log.error( self.name + ": " + self.handle.before )
5479 main.cleanup()
5480 main.exit()
5481 except NotImplementedError:
5482 main.log.exception( self.name + ": Json output not supported")
5483 return None
5484 except Exception:
5485 main.log.exception( self.name + ": Uncaught exception!" )
5486 main.cleanup()
5487 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005488
5489 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5490 '''
5491 Get the timestamp of searchTerm from karaf log.
5492
5493 Arguments:
5494 splitTerm_before and splitTerm_after:
5495
5496 The terms that split the string that contains the timeStamp of
5497 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5498 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5499 and the splitTerm_after is "x"
5500
5501 others:
5502
5503 plz look at the "logsearch" Function in onosclidriver.py
5504
5505
5506 '''
5507 if logNum < 0:
5508 main.log.error("Get wrong log number ")
5509 return main.ERROR
5510 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5511 if len(lines) == 0:
5512 main.log.warn( "Captured timestamp string is empty" )
5513 return main.ERROR
5514 lines = lines[ 0 ]
5515 try:
5516 assert type(lines) is str
5517 # get the target value
5518 line = lines.split( splitTerm_before )
5519 key = line[ 1 ].split( splitTerm_after )
5520 return int( key[ 0 ] )
5521 except IndexError:
5522 main.log.warn( "Index Error!" )
5523 return main.ERROR
5524 except AssertionError:
5525 main.log.warn( "Search Term Not Found " )
5526 return main.ERROR