blob: a348ee8ee867a985819127ce0188798db83ba1bb [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
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070032from cStringIO import StringIO
33from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040034
kelvin8ec71442015-01-15 16:57:00 -080035class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040036
kelvin8ec71442015-01-15 16:57:00 -080037 def __init__( self ):
38 """
39 Initialize client
40 """
Jon Hallefbd9792015-03-05 16:11:36 -080041 self.name = None
42 self.home = None
43 self.handle = None
You Wangdb8cd0a2016-05-26 15:19:45 -070044 self.graph = Graph()
kelvin8ec71442015-01-15 16:57:00 -080045 super( CLI, self ).__init__()
46
47 def connect( self, **connectargs ):
48 """
andrewonlab95ce8322014-10-13 14:12:04 -040049 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080050 """
andrewonlab95ce8322014-10-13 14:12:04 -040051 try:
52 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080053 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070054 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040055 for key in self.options:
56 if key == "home":
kelvin8ec71442015-01-15 16:57:00 -080057 self.home = self.options[ 'home' ]
andrewonlab95ce8322014-10-13 14:12:04 -040058 break
kelvin-onlabfb521662015-02-27 09:52:40 -080059 if self.home is None or self.home == "":
Jon Halle94919c2015-03-23 11:42:57 -070060 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040061
kelvin-onlaba4074292015-07-09 15:19:49 -070062 for key in self.options:
63 if key == 'onosIp':
64 self.onosIp = self.options[ 'onosIp' ]
65 break
66
kelvin8ec71442015-01-15 16:57:00 -080067 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070068
69 try:
Jon Hallc6793552016-01-19 14:18:37 -080070 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070071 self.ip_address = os.getenv( str( self.ip_address ) )
72 else:
73 main.log.info( self.name +
74 ": Trying to connect to " +
75 self.ip_address )
76
77 except KeyError:
78 main.log.info( "Invalid host name," +
79 " connecting to local host instead" )
80 self.ip_address = 'localhost'
81 except Exception as inst:
82 main.log.error( "Uncaught exception: " + str( inst ) )
83
kelvin8ec71442015-01-15 16:57:00 -080084 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -080085 user_name=self.user_name,
86 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -080087 port=self.port,
88 pwd=self.pwd,
89 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -040090
kelvin8ec71442015-01-15 16:57:00 -080091 self.handle.sendline( "cd " + self.home )
92 self.handle.expect( "\$" )
andrewonlab95ce8322014-10-13 14:12:04 -040093 if self.handle:
94 return self.handle
kelvin8ec71442015-01-15 16:57:00 -080095 else:
96 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -040097 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -080098 except TypeError:
99 main.log.exception( self.name + ": Object not as expected" )
100 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800102 main.log.error( self.name + ": EOF exception found" )
103 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400104 main.cleanup()
105 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800106 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800107 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400108 main.cleanup()
109 main.exit()
110
kelvin8ec71442015-01-15 16:57:00 -0800111 def disconnect( self ):
112 """
andrewonlab95ce8322014-10-13 14:12:04 -0400113 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800114 """
Jon Halld61331b2015-02-17 16:35:47 -0800115 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400116 try:
Jon Hall61282e32015-03-19 11:34:11 -0700117 if self.handle:
118 i = self.logout()
119 if i == main.TRUE:
120 self.handle.sendline( "" )
121 self.handle.expect( "\$" )
122 self.handle.sendline( "exit" )
123 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800124 except TypeError:
125 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800126 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800128 main.log.error( self.name + ": EOF exception found" )
129 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700130 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700131 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700132 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800134 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400135 response = main.FALSE
136 return response
137
kelvin8ec71442015-01-15 16:57:00 -0800138 def logout( self ):
139 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500140 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700141 Returns main.TRUE if exited CLI and
142 main.FALSE on timeout (not guranteed you are disconnected)
143 None on TypeError
144 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800145 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500146 try:
Jon Hall61282e32015-03-19 11:34:11 -0700147 if self.handle:
148 self.handle.sendline( "" )
149 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
150 timeout=10 )
151 if i == 0: # In ONOS CLI
152 self.handle.sendline( "logout" )
Jon Hallbfe00002016-04-05 10:23:54 -0700153 j = self.handle.expect( [ "\$",
154 "Command not found:",
155 pexpect.TIMEOUT ] )
156 if j == 0: # Successfully logged out
157 return main.TRUE
158 elif j == 1 or j == 2:
159 # ONOS didn't fully load, and logout command isn't working
160 # or the command timed out
161 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700162 try:
163 self.handle.expect( "\$" )
164 except pexpect.TIMEOUT:
165 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700166 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700167 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700168 main.log.warn( "Unknown repsonse to logout command: '{}'",
169 repr( self.handle.before ) )
170 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700171 elif i == 1: # not in CLI
172 return main.TRUE
173 elif i == 3: # Timeout
174 return main.FALSE
175 else:
andrewonlab9627f432014-11-14 12:45:10 -0500176 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800177 except TypeError:
178 main.log.exception( self.name + ": Object not as expected" )
179 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800181 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700182 main.log.error( self.name + ": " + self.handle.before )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500183 main.cleanup()
184 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700185 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700186 main.log.error( self.name +
187 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800188 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800189 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500190 main.cleanup()
191 main.exit()
192
kelvin-onlabd3b64892015-01-20 13:26:24 -0800193 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800194 """
andrewonlab95ce8322014-10-13 14:12:04 -0400195 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800196
andrewonlab95ce8322014-10-13 14:12:04 -0400197 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800198 """
andrewonlab95ce8322014-10-13 14:12:04 -0400199 try:
200 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800201 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400202 main.cleanup()
203 main.exit()
204 else:
kelvin8ec71442015-01-15 16:57:00 -0800205 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800206 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800207 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400208 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800209 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800210 handleBefore = self.handle.before
211 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800212 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800213 self.handle.sendline("")
214 self.handle.expect("\$")
andrew@onlab.usc400b112015-01-21 15:33:19 -0800215 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400216
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 main.log.info( "Cell call returned: " + handleBefore +
218 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400219
220 return main.TRUE
221
Jon Halld4d4b372015-01-28 16:02:41 -0800222 except TypeError:
223 main.log.exception( self.name + ": Object not as expected" )
224 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800226 main.log.error( self.name + ": eof exception found" )
227 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400228 main.cleanup()
229 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800230 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800231 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400232 main.cleanup()
233 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800234
pingping-lin57a56ce2015-05-20 16:43:48 -0700235 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800236 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800237 """
Jon Hallefbd9792015-03-05 16:11:36 -0800238 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 by user would be used to set the current karaf shell idle timeout.
240 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800241 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 Below is an example to start a session with 60 seconds idle timeout
243 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800244
Hari Krishna25d42f72015-01-05 15:08:28 -0800245 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800246 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800247
kelvin-onlabd3b64892015-01-20 13:26:24 -0800248 Note: karafTimeout is left as str so that this could be read
249 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800250 """
You Wangf69ab392016-01-26 16:34:38 -0800251 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400252 try:
Jon Hall67253832016-12-05 09:47:13 -0800253 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800254 self.handle.sendline( "" )
255 x = self.handle.expect( [
pingping-lin57a56ce2015-05-20 16:43:48 -0700256 "\$", "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500257 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800258 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500259 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400260
Jon Hall67253832016-12-05 09:47:13 -0800261 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800262 if waitForStart:
263 # Wait for onos start ( -w ) and enter onos cli
264 startCliCommand = "onos -w "
265 else:
266 startCliCommand = "onos "
267 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800268 i = self.handle.expect( [
269 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700270 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400271
272 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800273 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800274 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800275 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800276 "config:property-set -p org.apache.karaf.shell\
277 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800278 karafTimeout )
279 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800280 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800281 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400282 return main.TRUE
283 else:
kelvin8ec71442015-01-15 16:57:00 -0800284 # If failed, send ctrl+c to process and try again
285 main.log.info( "Starting CLI failed. Retrying..." )
286 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
289 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400290 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800291 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800292 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800293 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800295 "config:property-set -p org.apache.karaf.shell\
296 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800297 karafTimeout )
298 self.handle.expect( "\$" )
Chiyu Chengef109502016-11-21 15:51:38 -0800299 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800300 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400301 return main.TRUE
302 else:
kelvin8ec71442015-01-15 16:57:00 -0800303 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800304 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400305 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400306
Jon Halld4d4b372015-01-28 16:02:41 -0800307 except TypeError:
308 main.log.exception( self.name + ": Object not as expected" )
309 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400310 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800311 main.log.error( self.name + ": EOF exception found" )
312 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400313 main.cleanup()
314 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800315 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800316 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400317 main.cleanup()
318 main.exit()
319
suibin zhang116647a2016-05-06 16:30:09 -0700320 def startCellCli( self, karafTimeout="",
321 commandlineTimeout=10, onosStartTimeout=60 ):
322 """
323 Start CLI on onos ecll handle.
324
325 karafTimeout is an optional argument. karafTimeout value passed
326 by user would be used to set the current karaf shell idle timeout.
327 Note that when ever this property is modified the shell will exit and
328 the subsequent login would reflect new idle timeout.
329 Below is an example to start a session with 60 seconds idle timeout
330 ( input value is in milliseconds ):
331
332 tValue = "60000"
333
334 Note: karafTimeout is left as str so that this could be read
335 and passed to startOnosCli from PARAMS file as str.
336 """
337
338 try:
339 self.handle.sendline( "" )
340 x = self.handle.expect( [
341 "\$", "onos>" ], commandlineTimeout)
342
343 if x == 1:
344 main.log.info( "ONOS cli is already running" )
345 return main.TRUE
346
347 # Wait for onos start ( -w ) and enter onos cli
348 self.handle.sendline( "/opt/onos/bin/onos" )
349 i = self.handle.expect( [
350 "onos>",
351 pexpect.TIMEOUT ], onosStartTimeout )
352
353 if i == 0:
354 main.log.info( self.name + " CLI Started successfully" )
355 if karafTimeout:
356 self.handle.sendline(
357 "config:property-set -p org.apache.karaf.shell\
358 sshIdleTimeout " +
359 karafTimeout )
360 self.handle.expect( "\$" )
361 self.handle.sendline( "/opt/onos/bin/onos" )
362 self.handle.expect( "onos>" )
363 return main.TRUE
364 else:
365 # If failed, send ctrl+c to process and try again
366 main.log.info( "Starting CLI failed. Retrying..." )
367 self.handle.send( "\x03" )
368 self.handle.sendline( "/opt/onos/bin/onos" )
369 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
370 timeout=30 )
371 if i == 0:
372 main.log.info( self.name + " CLI Started " +
373 "successfully after retry attempt" )
374 if karafTimeout:
375 self.handle.sendline(
376 "config:property-set -p org.apache.karaf.shell\
377 sshIdleTimeout " +
378 karafTimeout )
379 self.handle.expect( "\$" )
380 self.handle.sendline( "/opt/onos/bin/onos" )
381 self.handle.expect( "onos>" )
382 return main.TRUE
383 else:
384 main.log.error( "Connection to CLI " +
385 self.name + " timeout" )
386 return main.FALSE
387
388 except TypeError:
389 main.log.exception( self.name + ": Object not as expected" )
390 return None
391 except pexpect.EOF:
392 main.log.error( self.name + ": EOF exception found" )
393 main.log.error( self.name + ": " + self.handle.before )
394 main.cleanup()
395 main.exit()
396 except Exception:
397 main.log.exception( self.name + ": Uncaught exception!" )
398 main.cleanup()
399 main.exit()
400
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800401 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800402 """
403 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800404 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800405 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700406 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800407 Available level: DEBUG, TRACE, INFO, WARN, ERROR
408 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800409 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800410 """
411 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800412 lvlStr = ""
413 if level:
414 lvlStr = "--level=" + level
415
kelvin-onlab338f5512015-02-06 10:53:16 -0800416 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700417 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800419
kelvin-onlab9f541032015-02-04 16:19:53 -0800420 response = self.handle.before
421 if re.search( "Error", response ):
422 return main.FALSE
423 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700424 except pexpect.TIMEOUT:
425 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700426 if noExit:
427 main.cleanup()
428 return None
429 else:
430 main.cleanup()
431 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800432 except pexpect.EOF:
433 main.log.error( self.name + ": EOF exception found" )
434 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700435 if noExit:
436 main.cleanup()
437 return None
438 else:
439 main.cleanup()
440 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800441 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800442 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700443 if noExit:
444 main.cleanup()
445 return None
446 else:
447 main.cleanup()
448 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400449
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700450 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800451 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800452 Send a completely user specified string to
453 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400454 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800455
YPZhang14a4aa92016-07-15 13:37:15 -0700456 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700457 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
458 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700459
andrewonlaba18f6bf2014-10-13 19:31:54 -0400460 Warning: There are no sanity checking to commands
461 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800462
kelvin8ec71442015-01-15 16:57:00 -0800463 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400464 try:
Jon Halla495f562016-05-16 18:03:26 -0700465 # Try to reconnect if disconnected from cli
466 self.handle.sendline( "" )
467 i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ] )
468 if i == 1:
469 main.log.error( self.name + ": onos cli session closed. ")
470 if self.onosIp:
471 main.log.warn( "Trying to reconnect " + self.onosIp )
472 reconnectResult = self.startOnosCli( self.onosIp )
473 if reconnectResult:
474 main.log.info( self.name + ": onos cli session reconnected." )
475 else:
476 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700477 if noExit:
478 return None
479 else:
480 main.cleanup()
481 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700482 else:
483 main.cleanup()
484 main.exit()
485 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700486 main.log.warn( "Timeout when testing cli responsiveness" )
487 main.log.debug( self.handle.before )
488 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700489 self.handle.expect( "onos>" )
490
Jon Hall14a03b52016-05-11 12:07:30 -0700491 if debug:
492 # NOTE: This adds and average of .4 seconds per call
493 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700494 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800495 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700496 if dollarSign:
497 i = self.handle.expect( ["onos>"], timeout )
498 else:
499 i = self.handle.expect( ["onos>", "\$"], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800500 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800501 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800502 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
503 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700504 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700505 main.log.debug( self.name + ": Raw output" )
506 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700507
508 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800509 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800510 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700511 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700512 main.log.debug( self.name + ": ansiEscape output" )
513 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514
kelvin-onlabfb521662015-02-27 09:52:40 -0800515 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800516 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700518 main.log.debug( self.name + ": Removed extra returns " +
519 "from output" )
520 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521
522 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800523 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700524 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700525 main.log.debug( self.name + ": parsed and stripped output" )
526 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700527
Jon Hall63604932015-02-26 17:09:50 -0800528 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700529 output = response.split( cmdStr.strip(), 1 )
530 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700531 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700533 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800534 output = output[1].strip()
535 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800536 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800537 return output
GlennRCed771242016-01-13 17:02:47 -0800538 except pexpect.TIMEOUT:
539 main.log.error( self.name + ":ONOS timeout" )
540 if debug:
541 main.log.debug( self.handle.before )
542 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 except IndexError:
544 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700545 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700546 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800547 except TypeError:
548 main.log.exception( self.name + ": Object not as expected" )
549 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400550 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800551 main.log.error( self.name + ": EOF exception found" )
552 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700553 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700554 return None
555 else:
556 main.cleanup()
557 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800558 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800559 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700560 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700561 return None
562 else:
563 main.cleanup()
564 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400565
kelvin8ec71442015-01-15 16:57:00 -0800566 # IMPORTANT NOTE:
567 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800568 # the cli command changing 'a:b' with 'aB'.
569 # Ex ) onos:topology > onosTopology
570 # onos:links > onosLinks
571 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800572
kelvin-onlabd3b64892015-01-20 13:26:24 -0800573 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800574 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400575 Adds a new cluster node by ID and address information.
576 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 * nodeId
578 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400579 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800580 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800581 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400582 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800583 cmdStr = "add-node " + str( nodeId ) + " " +\
584 str( ONOSIp ) + " " + str( tcpPort )
585 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700586 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800587 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800588 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800589 main.log.error( "Error in adding node" )
590 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800591 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400592 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800593 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400594 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800595 except AssertionError:
596 main.log.exception( "" )
597 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800598 except TypeError:
599 main.log.exception( self.name + ": Object not as expected" )
600 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800602 main.log.error( self.name + ": EOF exception found" )
603 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400604 main.cleanup()
605 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800606 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800607 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400608 main.cleanup()
609 main.exit()
610
kelvin-onlabd3b64892015-01-20 13:26:24 -0800611 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800612 """
andrewonlab86dc3082014-10-13 18:18:38 -0400613 Removes a cluster by ID
614 Issues command: 'remove-node [<node-id>]'
615 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800616 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800617 """
andrewonlab86dc3082014-10-13 18:18:38 -0400618 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400619
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700621 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700622 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800623 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700624 if re.search( "Error", handle ):
625 main.log.error( "Error in removing node" )
626 main.log.error( handle )
627 return main.FALSE
628 else:
629 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800630 except AssertionError:
631 main.log.exception( "" )
632 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800633 except TypeError:
634 main.log.exception( self.name + ": Object not as expected" )
635 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400636 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800637 main.log.error( self.name + ": EOF exception found" )
638 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400639 main.cleanup()
640 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800641 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800642 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400643 main.cleanup()
644 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400645
Jon Hall61282e32015-03-19 11:34:11 -0700646 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800647 """
andrewonlab7c211572014-10-15 16:45:20 -0400648 List the nodes currently visible
649 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700650 Optional argument:
651 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700654 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700655 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700656 cmdStr += " -j"
657 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700658 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800659 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 return output
Jon Hallc6793552016-01-19 14:18:37 -0800661 except AssertionError:
662 main.log.exception( "" )
663 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800664 except TypeError:
665 main.log.exception( self.name + ": Object not as expected" )
666 return None
andrewonlab7c211572014-10-15 16:45:20 -0400667 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800668 main.log.error( self.name + ": EOF exception found" )
669 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400670 main.cleanup()
671 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800672 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800673 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400674 main.cleanup()
675 main.exit()
676
kelvin8ec71442015-01-15 16:57:00 -0800677 def topology( self ):
678 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700679 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700680 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700681 Return:
682 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800683 """
andrewonlab95ce8322014-10-13 14:12:04 -0400684 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700685 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800687 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800688 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700689 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400690 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800691 except AssertionError:
692 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800693 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800694 except TypeError:
695 main.log.exception( self.name + ": Object not as expected" )
696 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400697 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800698 main.log.error( self.name + ": EOF exception found" )
699 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 main.cleanup()
701 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800703 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400704 main.cleanup()
705 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800706
jenkins7ead5a82015-03-13 10:28:21 -0700707 def deviceRemove( self, deviceId ):
708 """
709 Removes particular device from storage
710
711 TODO: refactor this function
712 """
713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "device-remove " + str( deviceId )
715 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800716 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800717 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700718 if re.search( "Error", handle ):
719 main.log.error( "Error in removing device" )
720 main.log.error( handle )
721 return main.FALSE
722 else:
723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
jenkins7ead5a82015-03-13 10:28:21 -0700727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
730 except pexpect.EOF:
731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
733 main.cleanup()
734 main.exit()
735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
737 main.cleanup()
738 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700739
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800741 """
Jon Hall7b02d952014-10-17 20:14:54 -0400742 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400743 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800744 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800745 """
andrewonlab86dc3082014-10-13 18:18:38 -0400746 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800748 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700749 cmdStr += " -j"
750 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800751 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800752 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800754 except AssertionError:
755 main.log.exception( "" )
756 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800757 except TypeError:
758 main.log.exception( self.name + ": Object not as expected" )
759 return None
andrewonlab7c211572014-10-15 16:45:20 -0400760 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800761 main.log.error( self.name + ": EOF exception found" )
762 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400763 main.cleanup()
764 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800765 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800766 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400767 main.cleanup()
768 main.exit()
769
kelvin-onlabd3b64892015-01-20 13:26:24 -0800770 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800771 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800772 This balances the devices across all controllers
773 by issuing command: 'onos> onos:balance-masters'
774 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800775 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800776 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800779 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800780 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 if re.search( "Error", handle ):
782 main.log.error( "Error in balancing masters" )
783 main.log.error( handle )
784 return main.FALSE
785 else:
786 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800787 except AssertionError:
788 main.log.exception( "" )
789 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800790 except TypeError:
791 main.log.exception( self.name + ": Object not as expected" )
792 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800793 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800794 main.log.error( self.name + ": EOF exception found" )
795 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800796 main.cleanup()
797 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800798 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800799 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800800 main.cleanup()
801 main.exit()
802
Jon Hallc6793552016-01-19 14:18:37 -0800803 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700804 """
805 Returns the output of the masters command.
806 Optional argument:
807 * jsonFormat - boolean indicating if you want output in json
808 """
809 try:
810 cmdStr = "onos:masters"
811 if jsonFormat:
812 cmdStr += " -j"
813 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700814 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800815 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700816 return output
Jon Hallc6793552016-01-19 14:18:37 -0800817 except AssertionError:
818 main.log.exception( "" )
819 return None
acsmars24950022015-07-30 18:00:43 -0700820 except TypeError:
821 main.log.exception( self.name + ": Object not as expected" )
822 return None
823 except pexpect.EOF:
824 main.log.error( self.name + ": EOF exception found" )
825 main.log.error( self.name + ": " + self.handle.before )
826 main.cleanup()
827 main.exit()
828 except Exception:
829 main.log.exception( self.name + ": Uncaught exception!" )
830 main.cleanup()
831 main.exit()
832
Jon Hallc6793552016-01-19 14:18:37 -0800833 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700834 """
835 Uses the master command to check that the devices' leadership
836 is evenly divided
837
838 Dependencies: checkMasters() and summary()
839
Jon Hall6509dbf2016-06-21 17:01:17 -0700840 Returns main.TRUE if the devices are balanced
841 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700842 Exits on Exception
843 Returns None on TypeError
844 """
845 try:
Jon Hallc6793552016-01-19 14:18:37 -0800846 summaryOutput = self.summary()
847 totalDevices = json.loads( summaryOutput )[ "devices" ]
848 except ( TypeError, ValueError ):
849 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
850 return None
851 try:
acsmars24950022015-07-30 18:00:43 -0700852 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800853 mastersOutput = self.checkMasters()
854 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700855 first = masters[ 0 ][ "size" ]
856 for master in masters:
857 totalOwnedDevices += master[ "size" ]
858 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
859 main.log.error( "Mastership not balanced" )
860 main.log.info( "\n" + self.checkMasters( False ) )
861 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700862 main.log.info( "Mastership balanced between " +
863 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700864 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800865 except ( TypeError, ValueError ):
866 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700867 return None
868 except pexpect.EOF:
869 main.log.error( self.name + ": EOF exception found" )
870 main.log.error( self.name + ": " + self.handle.before )
871 main.cleanup()
872 main.exit()
873 except Exception:
874 main.log.exception( self.name + ": Uncaught exception!" )
875 main.cleanup()
876 main.exit()
877
YPZhangfebf7302016-05-24 16:45:56 -0700878 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800879 """
Jon Halle8217482014-10-17 13:49:14 -0400880 Lists all core links
881 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800882 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800883 """
Jon Halle8217482014-10-17 13:49:14 -0400884 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700885 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800886 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700887 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700888 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800889 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800890 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700891 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800892 except AssertionError:
893 main.log.exception( "" )
894 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800895 except TypeError:
896 main.log.exception( self.name + ": Object not as expected" )
897 return None
Jon Halle8217482014-10-17 13:49:14 -0400898 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800899 main.log.error( self.name + ": EOF exception found" )
900 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400901 main.cleanup()
902 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800903 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800904 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400905 main.cleanup()
906 main.exit()
907
kelvin-onlabd3b64892015-01-20 13:26:24 -0800908 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800909 """
Jon Halle8217482014-10-17 13:49:14 -0400910 Lists all ports
911 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800912 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800913 """
Jon Halle8217482014-10-17 13:49:14 -0400914 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700915 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800916 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr += " -j"
918 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800919 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800920 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700921 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800922 except AssertionError:
923 main.log.exception( "" )
924 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800925 except TypeError:
926 main.log.exception( self.name + ": Object not as expected" )
927 return None
Jon Halle8217482014-10-17 13:49:14 -0400928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800929 main.log.error( self.name + ": EOF exception found" )
930 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400931 main.cleanup()
932 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800934 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400935 main.cleanup()
936 main.exit()
937
kelvin-onlabd3b64892015-01-20 13:26:24 -0800938 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Hall983a1702014-10-28 18:44:22 -0400940 Lists all devices and the controllers with roles assigned to them
941 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800943 """
andrewonlab7c211572014-10-15 16:45:20 -0400944 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700945 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700947 cmdStr += " -j"
948 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800949 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800950 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700951 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800952 except AssertionError:
953 main.log.exception( "" )
954 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800955 except TypeError:
956 main.log.exception( self.name + ": Object not as expected" )
957 return None
Jon Hall983a1702014-10-28 18:44:22 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400961 main.cleanup()
962 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800964 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400965 main.cleanup()
966 main.exit()
967
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800969 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800970 Given the a string containing the json representation of the "roles"
971 cli command and a partial or whole device id, returns a json object
972 containing the roles output for the first device whose id contains
973 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400974
975 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800976 A dict of the role assignments for the given device or
977 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800978 """
Jon Hall983a1702014-10-28 18:44:22 -0400979 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800980 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400981 return None
982 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 rawRoles = self.roles()
984 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800985 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800987 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800988 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400989 return device
990 return None
Jon Hallc6793552016-01-19 14:18:37 -0800991 except ( TypeError, ValueError ):
992 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800993 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400994 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800995 main.log.error( self.name + ": EOF exception found" )
996 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400997 main.cleanup()
998 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -04001001 main.cleanup()
1002 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001003
kelvin-onlabd3b64892015-01-20 13:26:24 -08001004 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001005 """
Jon Hall94fd0472014-12-08 11:52:42 -08001006 Iterates through each device and checks if there is a master assigned
1007 Returns: main.TRUE if each device has a master
1008 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001009 """
Jon Hall94fd0472014-12-08 11:52:42 -08001010 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 rawRoles = self.roles()
1012 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001013 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001015 # print device
1016 if device[ 'master' ] == "none":
1017 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001018 return main.FALSE
1019 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001020 except ( TypeError, ValueError ):
1021 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001022 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( self.name + ": EOF exception found" )
1025 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001026 main.cleanup()
1027 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001028 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001029 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001030 main.cleanup()
1031 main.exit()
1032
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001034 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001035 Returns string of paths, and the cost.
1036 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001037 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001038 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1040 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001042 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001043 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001044 main.log.error( "Error in getting paths" )
1045 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001046 else:
kelvin8ec71442015-01-15 16:57:00 -08001047 path = handle.split( ";" )[ 0 ]
1048 cost = handle.split( ";" )[ 1 ]
1049 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001050 except AssertionError:
1051 main.log.exception( "" )
1052 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001053 except TypeError:
1054 main.log.exception( self.name + ": Object not as expected" )
1055 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001056 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001057 main.log.error( self.name + ": EOF exception found" )
1058 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001059 main.cleanup()
1060 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001061 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001062 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001063 main.cleanup()
1064 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001065
kelvin-onlabd3b64892015-01-20 13:26:24 -08001066 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001067 """
Jon Hallffb386d2014-11-21 13:43:38 -08001068 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001069 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001070 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001071 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001072 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001073 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001075 cmdStr += " -j"
1076 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001077 if handle:
1078 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001079 # TODO: Maybe make this less hardcoded
1080 # ConsistentMap Exceptions
1081 assert "org.onosproject.store.service" not in handle
1082 # Node not leader
1083 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001084 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001085 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001086 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001087 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001088 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001089 except TypeError:
1090 main.log.exception( self.name + ": Object not as expected" )
1091 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001093 main.log.error( self.name + ": EOF exception found" )
1094 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001095 main.cleanup()
1096 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001098 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001099 main.cleanup()
1100 main.exit()
1101
kelvin-onlabd3b64892015-01-20 13:26:24 -08001102 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001103 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001104 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001105
Jon Hallefbd9792015-03-05 16:11:36 -08001106 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001107 partial mac address
1108
Jon Hall42db6dc2014-10-24 19:03:48 -04001109 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001110 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001111 try:
kelvin8ec71442015-01-15 16:57:00 -08001112 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001113 return None
1114 else:
1115 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 rawHosts = self.hosts()
1117 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001118 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001120 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001121 if not host:
1122 pass
1123 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001124 return host
1125 return None
Jon Hallc6793552016-01-19 14:18:37 -08001126 except ( TypeError, ValueError ):
1127 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001128 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001130 main.log.error( self.name + ": EOF exception found" )
1131 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001132 main.cleanup()
1133 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001134 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001135 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001136 main.cleanup()
1137 main.exit()
1138
kelvin-onlabd3b64892015-01-20 13:26:24 -08001139 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001140 """
1141 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001143
andrewonlab3f0a4af2014-10-17 12:25:14 -04001144 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 IMPORTANT:
1147 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001148 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001149 Furthermore, it assumes that value of VLAN is '-1'
1150 Description:
kelvin8ec71442015-01-15 16:57:00 -08001151 Converts mininet hosts ( h1, h2, h3... ) into
1152 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1153 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001154 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001156
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001158 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 hostHex = hex( int( host ) ).zfill( 12 )
1160 hostHex = str( hostHex ).replace( 'x', '0' )
1161 i = iter( str( hostHex ) )
1162 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1163 hostHex = hostHex + "/-1"
1164 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165
kelvin-onlabd3b64892015-01-20 13:26:24 -08001166 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001167
Jon Halld4d4b372015-01-28 16:02:41 -08001168 except TypeError:
1169 main.log.exception( self.name + ": Object not as expected" )
1170 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001171 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001172 main.log.error( self.name + ": EOF exception found" )
1173 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001174 main.cleanup()
1175 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001176 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001177 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001178 main.cleanup()
1179 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001180
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001181 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001182 """
andrewonlabe6745342014-10-17 14:29:13 -04001183 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 * hostIdOne: ONOS host id for host1
1185 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001186 Optional:
1187 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001188 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001189 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001190 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001191 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001192 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 Returns:
1194 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001195 """
andrewonlabe6745342014-10-17 14:29:13 -04001196 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001197 cmdStr = "add-host-intent "
1198 if vlanId:
1199 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001200 if setVlan:
1201 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001202 if encap:
1203 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001204 if bandwidth:
1205 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001206 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001207 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001208 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001209 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001210 if re.search( "Error", handle ):
1211 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001212 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001213 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001214 else:
1215 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001216 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1217 match = re.search('id=0x([\da-f]+),', handle)
1218 if match:
1219 return match.group()[3:-1]
1220 else:
1221 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001222 main.log.debug( "Response from ONOS was: " +
1223 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001224 return None
Jon Hallc6793552016-01-19 14:18:37 -08001225 except AssertionError:
1226 main.log.exception( "" )
1227 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001228 except TypeError:
1229 main.log.exception( self.name + ": Object not as expected" )
1230 return None
andrewonlabe6745342014-10-17 14:29:13 -04001231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001232 main.log.error( self.name + ": EOF exception found" )
1233 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001234 main.cleanup()
1235 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001236 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001237 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001238 main.cleanup()
1239 main.exit()
1240
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001242 """
andrewonlab7b31d232014-10-24 13:31:47 -04001243 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001244 * ingressDevice: device id of ingress device
1245 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001246 Optional:
1247 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001248 Description:
1249 Adds an optical intent by specifying an ingress and egress device
1250 Returns:
1251 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001252 """
andrewonlab7b31d232014-10-24 13:31:47 -04001253 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1255 " " + str( egressDevice )
1256 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001257 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001258 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001260 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001261 main.log.error( "Error in adding Optical intent" )
1262 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001263 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001264 main.log.info( "Optical intent installed between " +
1265 str( ingressDevice ) + " and " +
1266 str( egressDevice ) )
1267 match = re.search('id=0x([\da-f]+),', handle)
1268 if match:
1269 return match.group()[3:-1]
1270 else:
1271 main.log.error( "Error, intent ID not found" )
1272 return None
Jon Hallc6793552016-01-19 14:18:37 -08001273 except AssertionError:
1274 main.log.exception( "" )
1275 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001276 except TypeError:
1277 main.log.exception( self.name + ": Object not as expected" )
1278 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001279 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001280 main.log.error( self.name + ": EOF exception found" )
1281 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001282 main.cleanup()
1283 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001284 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001285 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001286 main.cleanup()
1287 main.exit()
1288
kelvin-onlabd3b64892015-01-20 13:26:24 -08001289 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001290 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001291 ingressDevice,
1292 egressDevice,
1293 portIngress="",
1294 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001295 ethType="",
1296 ethSrc="",
1297 ethDst="",
1298 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001300 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001301 ipProto="",
1302 ipSrc="",
1303 ipDst="",
1304 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001305 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001306 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001307 setVlan="",
1308 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001309 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001310 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001311 * ingressDevice: device id of ingress device
1312 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001313 Optional:
1314 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001315 * ethSrc: specify ethSrc ( i.e. src mac addr )
1316 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001317 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001318 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001319 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001320 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001321 * ipSrc: specify ip source address
1322 * ipDst: specify ip destination address
1323 * tcpSrc: specify tcp source port
1324 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001325 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001326 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001327 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001328 Description:
kelvin8ec71442015-01-15 16:57:00 -08001329 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001330 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001331 Returns:
1332 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001333
Jon Halle3f39ff2015-01-13 11:50:53 -08001334 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001335 options developers provide for point-to-point
1336 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001337 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001338 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001339 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001340
Jeremy Songsterff553672016-05-12 17:06:23 -07001341 if ethType:
1342 cmd += " --ethType " + str( ethType )
1343 if ethSrc:
1344 cmd += " --ethSrc " + str( ethSrc )
1345 if ethDst:
1346 cmd += " --ethDst " + str( ethDst )
1347 if bandwidth:
1348 cmd += " --bandwidth " + str( bandwidth )
1349 if lambdaAlloc:
1350 cmd += " --lambda "
1351 if ipProto:
1352 cmd += " --ipProto " + str( ipProto )
1353 if ipSrc:
1354 cmd += " --ipSrc " + str( ipSrc )
1355 if ipDst:
1356 cmd += " --ipDst " + str( ipDst )
1357 if tcpSrc:
1358 cmd += " --tcpSrc " + str( tcpSrc )
1359 if tcpDst:
1360 cmd += " --tcpDst " + str( tcpDst )
1361 if vlanId:
1362 cmd += " -v " + str( vlanId )
1363 if setVlan:
1364 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001365 if encap:
1366 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001367 if protected:
1368 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001369
kelvin8ec71442015-01-15 16:57:00 -08001370 # Check whether the user appended the port
1371 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001372 if "/" in ingressDevice:
1373 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001374 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001375 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001376 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001377 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 # Would it make sense to throw an exception and exit
1379 # the test?
1380 return None
andrewonlab36af3822014-11-18 17:48:18 -05001381
kelvin8ec71442015-01-15 16:57:00 -08001382 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 str( ingressDevice ) + "/" +\
1384 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001385
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 if "/" in egressDevice:
1387 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001388 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001390 main.log.error( "You must specify the egress port" )
1391 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001392
kelvin8ec71442015-01-15 16:57:00 -08001393 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001394 str( egressDevice ) + "/" +\
1395 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001396
kelvin-onlab898a6c62015-01-16 14:13:53 -08001397 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001398 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001399 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001400 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001401 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001402 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001403 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001404 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001405 # TODO: print out all the options in this message?
1406 main.log.info( "Point-to-point intent installed between " +
1407 str( ingressDevice ) + " and " +
1408 str( egressDevice ) )
1409 match = re.search('id=0x([\da-f]+),', handle)
1410 if match:
1411 return match.group()[3:-1]
1412 else:
1413 main.log.error( "Error, intent ID not found" )
1414 return None
Jon Hallc6793552016-01-19 14:18:37 -08001415 except AssertionError:
1416 main.log.exception( "" )
1417 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001418 except TypeError:
1419 main.log.exception( self.name + ": Object not as expected" )
1420 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001421 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001422 main.log.error( self.name + ": EOF exception found" )
1423 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001424 main.cleanup()
1425 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001426 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001427 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001428 main.cleanup()
1429 main.exit()
1430
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001432 self,
shahshreyac2f97072015-03-19 17:04:29 -07001433 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001435 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001437 ethType="",
1438 ethSrc="",
1439 ethDst="",
1440 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001441 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001442 ipProto="",
1443 ipSrc="",
1444 ipDst="",
1445 tcpSrc="",
1446 tcpDst="",
1447 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001448 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001449 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001450 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001451 partial=False,
1452 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001453 """
shahshreyad0c80432014-12-04 16:56:05 -08001454 Note:
shahshreya70622b12015-03-19 17:19:00 -07001455 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001456 is same. That is, all ingress devices include port numbers
1457 with a "/" or all ingress devices could specify device
1458 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001459 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001460 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001461 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001462 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001463 Optional:
1464 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001465 * ethSrc: specify ethSrc ( i.e. src mac addr )
1466 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001467 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001468 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001469 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001470 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001471 * ipSrc: specify ip source address
1472 * ipDst: specify ip destination address
1473 * tcpSrc: specify tcp source port
1474 * tcpDst: specify tcp destination port
1475 * setEthSrc: action to Rewrite Source MAC Address
1476 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001477 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001478 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001479 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001480 Description:
kelvin8ec71442015-01-15 16:57:00 -08001481 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001482 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 Returns:
1484 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001485
Jon Halle3f39ff2015-01-13 11:50:53 -08001486 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001487 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001488 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001489 """
shahshreyad0c80432014-12-04 16:56:05 -08001490 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001491 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001492
Jeremy Songsterff553672016-05-12 17:06:23 -07001493 if ethType:
1494 cmd += " --ethType " + str( ethType )
1495 if ethSrc:
1496 cmd += " --ethSrc " + str( ethSrc )
1497 if ethDst:
1498 cmd += " --ethDst " + str( ethDst )
1499 if bandwidth:
1500 cmd += " --bandwidth " + str( bandwidth )
1501 if lambdaAlloc:
1502 cmd += " --lambda "
1503 if ipProto:
1504 cmd += " --ipProto " + str( ipProto )
1505 if ipSrc:
1506 cmd += " --ipSrc " + str( ipSrc )
1507 if ipDst:
1508 cmd += " --ipDst " + str( ipDst )
1509 if tcpSrc:
1510 cmd += " --tcpSrc " + str( tcpSrc )
1511 if tcpDst:
1512 cmd += " --tcpDst " + str( tcpDst )
1513 if setEthSrc:
1514 cmd += " --setEthSrc " + str( setEthSrc )
1515 if setEthDst:
1516 cmd += " --setEthDst " + str( setEthDst )
1517 if vlanId:
1518 cmd += " -v " + str( vlanId )
1519 if setVlan:
1520 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001521 if partial:
1522 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001523 if encap:
1524 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001525
kelvin8ec71442015-01-15 16:57:00 -08001526 # Check whether the user appended the port
1527 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001528
1529 if portIngressList is None:
1530 for ingressDevice in ingressDeviceList:
1531 if "/" in ingressDevice:
1532 cmd += " " + str( ingressDevice )
1533 else:
1534 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001535 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001536 # TODO: perhaps more meaningful return
1537 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001538 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001539 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001540 for ingressDevice, portIngress in zip( ingressDeviceList,
1541 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001542 cmd += " " + \
1543 str( ingressDevice ) + "/" +\
1544 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001545 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001546 main.log.error( "Device list and port list does not " +
1547 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001548 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 if "/" in egressDevice:
1550 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001551 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001553 main.log.error( "You must specify " +
1554 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001555 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001556
kelvin8ec71442015-01-15 16:57:00 -08001557 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 str( egressDevice ) + "/" +\
1559 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001560 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001561 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001562 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001563 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001564 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001565 main.log.error( "Error in adding multipoint-to-singlepoint " +
1566 "intent" )
1567 return None
shahshreyad0c80432014-12-04 16:56:05 -08001568 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001569 match = re.search('id=0x([\da-f]+),', handle)
1570 if match:
1571 return match.group()[3:-1]
1572 else:
1573 main.log.error( "Error, intent ID not found" )
1574 return None
Jon Hallc6793552016-01-19 14:18:37 -08001575 except AssertionError:
1576 main.log.exception( "" )
1577 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001578 except TypeError:
1579 main.log.exception( self.name + ": Object not as expected" )
1580 return None
1581 except pexpect.EOF:
1582 main.log.error( self.name + ": EOF exception found" )
1583 main.log.error( self.name + ": " + self.handle.before )
1584 main.cleanup()
1585 main.exit()
1586 except Exception:
1587 main.log.exception( self.name + ": Uncaught exception!" )
1588 main.cleanup()
1589 main.exit()
1590
1591 def addSinglepointToMultipointIntent(
1592 self,
1593 ingressDevice,
1594 egressDeviceList,
1595 portIngress="",
1596 portEgressList=None,
1597 ethType="",
1598 ethSrc="",
1599 ethDst="",
1600 bandwidth="",
1601 lambdaAlloc=False,
1602 ipProto="",
1603 ipSrc="",
1604 ipDst="",
1605 tcpSrc="",
1606 tcpDst="",
1607 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001608 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001609 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001610 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001611 partial=False,
1612 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001613 """
1614 Note:
1615 This function assumes the format of all egress devices
1616 is same. That is, all egress devices include port numbers
1617 with a "/" or all egress devices could specify device
1618 ids and port numbers seperately.
1619 Required:
1620 * EgressDeviceList: List of device ids of egress device
1621 ( Atleast 2 eress devices required in the list )
1622 * ingressDevice: device id of ingress device
1623 Optional:
1624 * ethType: specify ethType
1625 * ethSrc: specify ethSrc ( i.e. src mac addr )
1626 * ethDst: specify ethDst ( i.e. dst mac addr )
1627 * bandwidth: specify bandwidth capacity of link
1628 * lambdaAlloc: if True, intent will allocate lambda
1629 for the specified intent
1630 * ipProto: specify ip protocol
1631 * ipSrc: specify ip source address
1632 * ipDst: specify ip destination address
1633 * tcpSrc: specify tcp source port
1634 * tcpDst: specify tcp destination port
1635 * setEthSrc: action to Rewrite Source MAC Address
1636 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001637 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001638 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001639 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001640 Description:
1641 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1642 specifying device id's and optional fields
1643 Returns:
1644 A string of the intent id or None on error
1645
1646 NOTE: This function may change depending on the
1647 options developers provide for singlepoint-to-multipoint
1648 intent via cli
1649 """
1650 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001651 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001652
Jeremy Songsterff553672016-05-12 17:06:23 -07001653 if ethType:
1654 cmd += " --ethType " + str( ethType )
1655 if ethSrc:
1656 cmd += " --ethSrc " + str( ethSrc )
1657 if ethDst:
1658 cmd += " --ethDst " + str( ethDst )
1659 if bandwidth:
1660 cmd += " --bandwidth " + str( bandwidth )
1661 if lambdaAlloc:
1662 cmd += " --lambda "
1663 if ipProto:
1664 cmd += " --ipProto " + str( ipProto )
1665 if ipSrc:
1666 cmd += " --ipSrc " + str( ipSrc )
1667 if ipDst:
1668 cmd += " --ipDst " + str( ipDst )
1669 if tcpSrc:
1670 cmd += " --tcpSrc " + str( tcpSrc )
1671 if tcpDst:
1672 cmd += " --tcpDst " + str( tcpDst )
1673 if setEthSrc:
1674 cmd += " --setEthSrc " + str( setEthSrc )
1675 if setEthDst:
1676 cmd += " --setEthDst " + str( setEthDst )
1677 if vlanId:
1678 cmd += " -v " + str( vlanId )
1679 if setVlan:
1680 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001681 if partial:
1682 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001683 if encap:
1684 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001685
1686 # Check whether the user appended the port
1687 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001688
kelvin-onlabb9408212015-04-01 13:34:04 -07001689 if "/" in ingressDevice:
1690 cmd += " " + str( ingressDevice )
1691 else:
1692 if not portIngress:
1693 main.log.error( "You must specify " +
1694 "the Ingress port" )
1695 return main.FALSE
1696
1697 cmd += " " +\
1698 str( ingressDevice ) + "/" +\
1699 str( portIngress )
1700
1701 if portEgressList is None:
1702 for egressDevice in egressDeviceList:
1703 if "/" in egressDevice:
1704 cmd += " " + str( egressDevice )
1705 else:
1706 main.log.error( "You must specify " +
1707 "the egress port" )
1708 # TODO: perhaps more meaningful return
1709 return main.FALSE
1710 else:
1711 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001712 for egressDevice, portEgress in zip( egressDeviceList,
1713 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001714 cmd += " " + \
1715 str( egressDevice ) + "/" +\
1716 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001717 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001718 main.log.error( "Device list and port list does not " +
1719 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001720 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001721 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001722 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001723 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001724 # If error, return error message
1725 if re.search( "Error", handle ):
1726 main.log.error( "Error in adding singlepoint-to-multipoint " +
1727 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001728 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001729 else:
1730 match = re.search('id=0x([\da-f]+),', handle)
1731 if match:
1732 return match.group()[3:-1]
1733 else:
1734 main.log.error( "Error, intent ID not found" )
1735 return None
Jon Hallc6793552016-01-19 14:18:37 -08001736 except AssertionError:
1737 main.log.exception( "" )
1738 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001739 except TypeError:
1740 main.log.exception( self.name + ": Object not as expected" )
1741 return None
shahshreyad0c80432014-12-04 16:56:05 -08001742 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001743 main.log.error( self.name + ": EOF exception found" )
1744 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001745 main.cleanup()
1746 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001747 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001748 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001749 main.cleanup()
1750 main.exit()
1751
Hari Krishna9e232602015-04-13 17:29:08 -07001752 def addMplsIntent(
1753 self,
1754 ingressDevice,
1755 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001756 ingressPort="",
1757 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001758 ethType="",
1759 ethSrc="",
1760 ethDst="",
1761 bandwidth="",
1762 lambdaAlloc=False,
1763 ipProto="",
1764 ipSrc="",
1765 ipDst="",
1766 tcpSrc="",
1767 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001768 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001769 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001770 priority=""):
1771 """
1772 Required:
1773 * ingressDevice: device id of ingress device
1774 * egressDevice: device id of egress device
1775 Optional:
1776 * ethType: specify ethType
1777 * ethSrc: specify ethSrc ( i.e. src mac addr )
1778 * ethDst: specify ethDst ( i.e. dst mac addr )
1779 * bandwidth: specify bandwidth capacity of link
1780 * lambdaAlloc: if True, intent will allocate lambda
1781 for the specified intent
1782 * ipProto: specify ip protocol
1783 * ipSrc: specify ip source address
1784 * ipDst: specify ip destination address
1785 * tcpSrc: specify tcp source port
1786 * tcpDst: specify tcp destination port
1787 * ingressLabel: Ingress MPLS label
1788 * egressLabel: Egress MPLS label
1789 Description:
1790 Adds MPLS intent by
1791 specifying device id's and optional fields
1792 Returns:
1793 A string of the intent id or None on error
1794
1795 NOTE: This function may change depending on the
1796 options developers provide for MPLS
1797 intent via cli
1798 """
1799 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001800 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001801
Jeremy Songsterff553672016-05-12 17:06:23 -07001802 if ethType:
1803 cmd += " --ethType " + str( ethType )
1804 if ethSrc:
1805 cmd += " --ethSrc " + str( ethSrc )
1806 if ethDst:
1807 cmd += " --ethDst " + str( ethDst )
1808 if bandwidth:
1809 cmd += " --bandwidth " + str( bandwidth )
1810 if lambdaAlloc:
1811 cmd += " --lambda "
1812 if ipProto:
1813 cmd += " --ipProto " + str( ipProto )
1814 if ipSrc:
1815 cmd += " --ipSrc " + str( ipSrc )
1816 if ipDst:
1817 cmd += " --ipDst " + str( ipDst )
1818 if tcpSrc:
1819 cmd += " --tcpSrc " + str( tcpSrc )
1820 if tcpDst:
1821 cmd += " --tcpDst " + str( tcpDst )
1822 if ingressLabel:
1823 cmd += " --ingressLabel " + str( ingressLabel )
1824 if egressLabel:
1825 cmd += " --egressLabel " + str( egressLabel )
1826 if priority:
1827 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001828
1829 # Check whether the user appended the port
1830 # or provided it as an input
1831 if "/" in ingressDevice:
1832 cmd += " " + str( ingressDevice )
1833 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001834 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001835 main.log.error( "You must specify the ingress port" )
1836 return None
1837
1838 cmd += " " + \
1839 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001840 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001841
1842 if "/" in egressDevice:
1843 cmd += " " + str( egressDevice )
1844 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001845 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001846 main.log.error( "You must specify the egress port" )
1847 return None
1848
1849 cmd += " " +\
1850 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001851 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001852
1853 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001854 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001855 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001856 # If error, return error message
1857 if re.search( "Error", handle ):
1858 main.log.error( "Error in adding mpls intent" )
1859 return None
1860 else:
1861 # TODO: print out all the options in this message?
1862 main.log.info( "MPLS intent installed between " +
1863 str( ingressDevice ) + " and " +
1864 str( egressDevice ) )
1865 match = re.search('id=0x([\da-f]+),', handle)
1866 if match:
1867 return match.group()[3:-1]
1868 else:
1869 main.log.error( "Error, intent ID not found" )
1870 return None
Jon Hallc6793552016-01-19 14:18:37 -08001871 except AssertionError:
1872 main.log.exception( "" )
1873 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001874 except TypeError:
1875 main.log.exception( self.name + ": Object not as expected" )
1876 return None
1877 except pexpect.EOF:
1878 main.log.error( self.name + ": EOF exception found" )
1879 main.log.error( self.name + ": " + self.handle.before )
1880 main.cleanup()
1881 main.exit()
1882 except Exception:
1883 main.log.exception( self.name + ": Uncaught exception!" )
1884 main.cleanup()
1885 main.exit()
1886
Jon Hallefbd9792015-03-05 16:11:36 -08001887 def removeIntent( self, intentId, app='org.onosproject.cli',
1888 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001889 """
shahshreya1c818fc2015-02-26 13:44:08 -08001890 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001891 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001892 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001893 -p or --purge: Purge the intent from the store after removal
1894
Jon Halle3f39ff2015-01-13 11:50:53 -08001895 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001896 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001897 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001898 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001899 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001900 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001901 if purge:
1902 cmdStr += " -p"
1903 if sync:
1904 cmdStr += " -s"
1905
1906 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001909 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001910 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001911 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001912 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001913 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001914 # TODO: Should this be main.TRUE
1915 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001916 except AssertionError:
1917 main.log.exception( "" )
1918 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001919 except TypeError:
1920 main.log.exception( self.name + ": Object not as expected" )
1921 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001922 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001923 main.log.error( self.name + ": EOF exception found" )
1924 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001925 main.cleanup()
1926 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001927 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001928 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001929 main.cleanup()
1930 main.exit()
1931
YPZhangfebf7302016-05-24 16:45:56 -07001932 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001933 """
1934 Description:
1935 Remove all the intents
1936 Optional args:-
1937 -s or --sync: Waits for the removal before returning
1938 -p or --purge: Purge the intent from the store after removal
1939 Returns:
1940 Returns main.TRUE if all intents are removed, otherwise returns
1941 main.FALSE; Returns None for exception
1942 """
1943 try:
1944 cmdStr = "remove-intent"
1945 if purge:
1946 cmdStr += " -p"
1947 if sync:
1948 cmdStr += " -s"
1949
1950 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001951 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001952 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001953 assert "Command not found:" not in handle, handle
1954 if re.search( "Error", handle ):
1955 main.log.error( "Error in removing intent" )
1956 return main.FALSE
1957 else:
1958 return main.TRUE
1959 except AssertionError:
1960 main.log.exception( "" )
1961 return None
1962 except TypeError:
1963 main.log.exception( self.name + ": Object not as expected" )
1964 return None
1965 except pexpect.EOF:
1966 main.log.error( self.name + ": EOF exception found" )
1967 main.log.error( self.name + ": " + self.handle.before )
1968 main.cleanup()
1969 main.exit()
1970 except Exception:
1971 main.log.exception( self.name + ": Uncaught exception!" )
1972 main.cleanup()
1973 main.exit()
1974
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001975 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001976 """
1977 Purges all WITHDRAWN Intents
1978 """
1979 try:
1980 cmdStr = "purge-intents"
1981 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001982 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001983 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001984 if re.search( "Error", handle ):
1985 main.log.error( "Error in purging intents" )
1986 return main.FALSE
1987 else:
1988 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001989 except AssertionError:
1990 main.log.exception( "" )
1991 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001992 except TypeError:
1993 main.log.exception( self.name + ": Object not as expected" )
1994 return None
1995 except pexpect.EOF:
1996 main.log.error( self.name + ": EOF exception found" )
1997 main.log.error( self.name + ": " + self.handle.before )
1998 main.cleanup()
1999 main.exit()
2000 except Exception:
2001 main.log.exception( self.name + ": Uncaught exception!" )
2002 main.cleanup()
2003 main.exit()
2004
kelvin-onlabd3b64892015-01-20 13:26:24 -08002005 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002006 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002007 NOTE: This method should be used after installing application:
2008 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002009 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002011 Description:
2012 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002013 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002014 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002015 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002016 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002017 cmdStr += " -j"
2018 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002019 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002020 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002021 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002022 except AssertionError:
2023 main.log.exception( "" )
2024 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002025 except TypeError:
2026 main.log.exception( self.name + ": Object not as expected" )
2027 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002028 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002029 main.log.error( self.name + ": EOF exception found" )
2030 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002031 main.cleanup()
2032 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002034 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002035 main.cleanup()
2036 main.exit()
2037
pingping-lin54b03372015-08-13 14:43:10 -07002038 def ipv4RouteNumber( self ):
2039 """
2040 NOTE: This method should be used after installing application:
2041 onos-app-sdnip
2042 Description:
2043 Obtain the total IPv4 routes number in the system
2044 """
2045 try:
Pratik Parab57963572017-05-09 11:37:54 -07002046 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002047 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002048 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002049 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002050 jsonResult = json.loads( handle )
Pratik Parab57963572017-05-09 11:37:54 -07002051 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002052 except AssertionError:
2053 main.log.exception( "" )
2054 return None
2055 except ( TypeError, ValueError ):
2056 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002057 return None
2058 except pexpect.EOF:
2059 main.log.error( self.name + ": EOF exception found" )
2060 main.log.error( self.name + ": " + self.handle.before )
2061 main.cleanup()
2062 main.exit()
2063 except Exception:
2064 main.log.exception( self.name + ": Uncaught exception!" )
2065 main.cleanup()
2066 main.exit()
2067
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002068 #=============Function to check Bandwidth allocation========
2069 def allocations( self, jsonFormat = True, dollarSign = True ):
2070 """
2071 Description:
2072 Obtain Bandwidth Allocation Information from ONOS cli.
2073 """
2074 try:
2075 cmdStr = "allocations"
2076 if jsonFormat:
2077 cmdStr += " -j"
2078 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2079 assert handle is not None, "Error in sendline"
2080 assert "Command not found:" not in handle, handle
2081 return handle
2082 except AssertionError:
2083 main.log.exception( "" )
2084 return None
2085 except ( TypeError, ValueError ):
2086 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2087 return None
2088 except pexpect.EOF:
2089 main.log.error( self.name + ": EOF exception found" )
2090 main.log.error( self.name + ": " + self.handle.before )
2091 main.cleanup()
2092 main.exit()
2093 except Exception:
2094 main.log.exception( self.name + ": Uncaught exception!" )
2095 main.cleanup()
2096 main.exit()
2097
pingping-lin8244a3b2015-09-16 13:36:56 -07002098 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002099 """
andrewonlabe6745342014-10-17 14:29:13 -04002100 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002101 Obtain intents from the ONOS cli.
2102 Optional:
2103 * jsonFormat: Enable output formatting in json, default to True
2104 * summary: Whether only output the intent summary, defaults to False
2105 * type: Only output a certain type of intent. This options is valid
2106 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002107 """
andrewonlabe6745342014-10-17 14:29:13 -04002108 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002109 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002110 if summary:
2111 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002112 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002113 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002114 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002115 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002116 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002117 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002118 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002119 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002120 else:
Jon Hallff566d52016-01-15 14:45:36 -08002121 intentType = ""
2122 # IF we want the summary of a specific intent type
2123 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002124 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002125 if intentType in jsonResult.keys():
2126 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002127 else:
Jon Hallff566d52016-01-15 14:45:36 -08002128 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002129 return handle
2130 else:
2131 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002132 except AssertionError:
2133 main.log.exception( "" )
2134 return None
2135 except ( TypeError, ValueError ):
2136 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002137 return None
2138 except pexpect.EOF:
2139 main.log.error( self.name + ": EOF exception found" )
2140 main.log.error( self.name + ": " + self.handle.before )
2141 main.cleanup()
2142 main.exit()
2143 except Exception:
2144 main.log.exception( self.name + ": Uncaught exception!" )
2145 main.cleanup()
2146 main.exit()
2147
kelvin-onlab54400a92015-02-26 18:05:51 -08002148 def getIntentState(self, intentsId, intentsJson=None):
2149 """
You Wangfdcbfc42016-05-16 12:16:53 -07002150 Description:
2151 Gets intent state. Accepts a single intent ID (string type) or a
2152 list of intent IDs.
2153 Parameters:
2154 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002155 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002156 Returns:
2157 Returns the state (string type) of the ID if a single intent ID is
2158 accepted.
2159 Returns a list of dictionaries if a list of intent IDs is accepted,
2160 and each dictionary maps 'id' to the Intent ID and 'state' to
2161 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002162 """
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002163
kelvin-onlab54400a92015-02-26 18:05:51 -08002164 try:
2165 state = "State is Undefined"
2166 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002167 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002168 else:
Jon Hallc6793552016-01-19 14:18:37 -08002169 rawJson = intentsJson
2170 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002171 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002172 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002173 if intentsId == intent[ 'id' ]:
2174 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002176 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002177 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002178 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002179 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002180 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002181 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002182 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002183 for intent in parsedIntentsJson:
2184 if intentsId[ i ] == intent[ 'id' ]:
2185 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002186 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002187 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002188 break
Jon Hallefbd9792015-03-05 16:11:36 -08002189 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002190 main.log.warn( "Could not find all intents in ONOS output" )
2191 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002192 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002193 else:
Jon Hall53158082017-05-18 11:17:00 -07002194 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002195 return None
Jon Hallc6793552016-01-19 14:18:37 -08002196 except ( TypeError, ValueError ):
2197 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002198 return None
2199 except pexpect.EOF:
2200 main.log.error( self.name + ": EOF exception found" )
2201 main.log.error( self.name + ": " + self.handle.before )
2202 main.cleanup()
2203 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002204 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002205 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002206 main.cleanup()
2207 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002208
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002209 def checkIntentState( self, intentsId, bandwidthFlag=False, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002210 """
2211 Description:
2212 Check intents state
2213 Required:
2214 intentsId - List of intents ID to be checked
2215 Optional:
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002216 bandwidthFlag - Check the bandwidth allocations. If bandwidth is
2217 specified, then check for bandwidth allocations
kelvin-onlabf512e942015-06-08 19:42:59 -07002218 expectedState - Check the expected state(s) of each intents
2219 state in the list.
2220 *NOTE: You can pass in a list of expected state,
2221 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002222 Return:
Jon Hall53158082017-05-18 11:17:00 -07002223 Returns main.TRUE only if all intent are the same as expected states,
2224 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002225 """
2226 try:
2227 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002228 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002229 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002230 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002231 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002232 "getting intents state" )
2233 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002234
Jon Hall53158082017-05-18 11:17:00 -07002235 bandwidthFailed = False
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002236 if bandwidthFlag:
2237 rawAlloc = self.allocations()
2238 expectedFormat = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
2239 ONOSOutput = StringIO(rawAlloc)
Jon Hall53158082017-05-18 11:17:00 -07002240 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str(ONOSOutput), str( expectedFormat ) ) )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002241
Jon Hall53158082017-05-18 11:17:00 -07002242 for actual, expected in izip( ONOSOutput, expectedFormat ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002243 actual = actual.rstrip()
2244 expected = expected.rstrip()
Jon Hall53158082017-05-18 11:17:00 -07002245 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002246 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2247 marker1 = actual.find('allocated')
2248 m1 = actual[:marker1]
2249 marker2 = expected.find('allocated')
2250 m2 = expected[:marker2]
2251 if m1 != m2:
Jon Hall53158082017-05-18 11:17:00 -07002252 bandwidthFailed = True
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002253 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
Jon Hall53158082017-05-18 11:17:00 -07002254 bandwidthFailed = True
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002255
2256 expectedFormat.close()
2257 ONOSOutput.close()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002258
Jon Hall53158082017-05-18 11:17:00 -07002259 if bandwidthFailed:
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002260 main.log.error("Bandwidth not allocated correctly using Intents!!")
2261 returnValue = main.FALSE
2262 return returnValue
2263
kelvin-onlabf512e942015-06-08 19:42:59 -07002264 if isinstance( expectedState, types.StringType ):
2265 for intents in intentsDict:
2266 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002267 main.log.debug( self.name + " : Intent ID - " +
2268 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002269 " actual state = " +
2270 intents.get( 'state' )
2271 + " does not equal expected state = "
2272 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002273 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002274
2275 elif isinstance( expectedState, types.ListType ):
2276 for intents in intentsDict:
2277 if not any( state == intents.get( 'state' ) for state in
2278 expectedState ):
2279 main.log.debug( self.name + " : Intent ID - " +
2280 intents.get( 'id' ) +
2281 " actual state = " +
2282 intents.get( 'state' ) +
2283 " does not equal expected states = "
2284 + str( expectedState ) )
2285 returnValue = main.FALSE
2286
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002287 if returnValue == main.TRUE:
2288 main.log.info( self.name + ": All " +
2289 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002290 " intents are in " + str( expectedState ) +
2291 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002292 return returnValue
2293 except TypeError:
2294 main.log.exception( self.name + ": Object not as expected" )
2295 return None
2296 except pexpect.EOF:
2297 main.log.error( self.name + ": EOF exception found" )
2298 main.log.error( self.name + ": " + self.handle.before )
2299 main.cleanup()
2300 main.exit()
2301 except Exception:
2302 main.log.exception( self.name + ": Uncaught exception!" )
2303 main.cleanup()
2304 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002305
You Wang66518af2016-05-16 15:32:59 -07002306 def compareIntent( self, intentDict ):
2307 """
2308 Description:
2309 Compare the intent ids and states provided in the argument with all intents in ONOS
2310 Return:
2311 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2312 Arguments:
2313 intentDict: a dictionary which maps intent ids to intent states
2314 """
2315 try:
2316 intentsRaw = self.intents()
2317 intentsJson = json.loads( intentsRaw )
2318 intentDictONOS = {}
2319 for intent in intentsJson:
2320 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002321 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002322 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002323 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002324 str( len( intentDict ) ) + " expected and " +
2325 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002326 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002327 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002328 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002329 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2330 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002331 else:
2332 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2333 main.log.debug( self.name + ": intent ID - " + intentID +
2334 " expected state is " + intentDict[ intentID ] +
2335 " but actual state is " + intentDictONOS[ intentID ] )
2336 returnValue = main.FALSE
2337 intentDictONOS.pop( intentID )
2338 if len( intentDictONOS ) > 0:
2339 returnValue = main.FALSE
2340 for intentID in intentDictONOS.keys():
2341 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002342 if returnValue == main.TRUE:
2343 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2344 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002345 except KeyError:
2346 main.log.exception( self.name + ": KeyError exception found" )
2347 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002348 except ( TypeError, ValueError ):
2349 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002350 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002351 except pexpect.EOF:
2352 main.log.error( self.name + ": EOF exception found" )
2353 main.log.error( self.name + ": " + self.handle.before )
2354 main.cleanup()
2355 main.exit()
2356 except Exception:
2357 main.log.exception( self.name + ": Uncaught exception!" )
2358 main.cleanup()
2359 main.exit()
2360
YPZhang14a4aa92016-07-15 13:37:15 -07002361 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002362 """
2363 Description:
2364 Check the number of installed intents.
2365 Optional:
2366 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002367 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002368 Return:
2369 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2370 , otherwise, returns main.FALSE.
2371 """
2372
2373 try:
2374 cmd = "intents -s -j"
2375
2376 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002377 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002378 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002379 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002380 response = json.loads( response )
2381
2382 # get total and installed number, see if they are match
2383 allState = response.get( 'all' )
2384 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002385 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002386 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002387 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002388 return main.FALSE
2389
Jon Hallc6793552016-01-19 14:18:37 -08002390 except ( TypeError, ValueError ):
2391 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002392 return None
2393 except pexpect.EOF:
2394 main.log.error( self.name + ": EOF exception found" )
2395 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002396 if noExit:
2397 return main.FALSE
2398 else:
2399 main.cleanup()
2400 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002401 except pexpect.TIMEOUT:
2402 main.log.error( self.name + ": ONOS timeout" )
2403 return None
GlennRCed771242016-01-13 17:02:47 -08002404 except Exception:
2405 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002406 if noExit:
2407 return main.FALSE
2408 else:
2409 main.cleanup()
2410 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002411
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002412 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002413 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002414 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002415 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002416 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002417 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002418 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002419 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002420 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002421 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002422 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002423 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002424 if noCore:
2425 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002426 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002427 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002428 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002429 assert "Command not found:" not in handle, handle
2430 if re.search( "Error:", handle ):
2431 main.log.error( self.name + ": flows() response: " +
2432 str( handle ) )
2433 return handle
2434 except AssertionError:
2435 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002436 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002437 except TypeError:
2438 main.log.exception( self.name + ": Object not as expected" )
2439 return None
Jon Hallc6793552016-01-19 14:18:37 -08002440 except pexpect.TIMEOUT:
2441 main.log.error( self.name + ": ONOS timeout" )
2442 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002443 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002444 main.log.error( self.name + ": EOF exception found" )
2445 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002446 main.cleanup()
2447 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002448 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002449 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002450 main.cleanup()
2451 main.exit()
2452
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002453 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002454 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002455 count = int( count ) if count else 0
2456 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002457
Jon Halle0f0b342017-04-18 11:43:47 -07002458 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002459 """
2460 Description:
GlennRCed771242016-01-13 17:02:47 -08002461 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002462 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2463 if the count of those states is 0, which means all current flows
2464 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002465 Optional:
GlennRCed771242016-01-13 17:02:47 -08002466 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002467 Return:
2468 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002469 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002470 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002471 """
2472 try:
GlennRCed771242016-01-13 17:02:47 -08002473 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2474 checkedStates = []
2475 statesCount = [0, 0, 0, 0]
2476 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002477 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002478 if rawFlows:
2479 # if we didn't get flows or flows function return None, we should return
2480 # main.Flase
2481 checkedStates.append( json.loads( rawFlows ) )
2482 else:
2483 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002484 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002485 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002486 try:
2487 statesCount[i] += int( c.get( "flowCount" ) )
2488 except TypeError:
2489 main.log.exception( "Json object not as expected" )
2490 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002491
GlennRCed771242016-01-13 17:02:47 -08002492 # We want to count PENDING_ADD if isPENDING is true
2493 if isPENDING:
2494 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2495 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002496 else:
GlennRCed771242016-01-13 17:02:47 -08002497 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2498 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002499 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002500 except ( TypeError, ValueError ):
2501 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002502 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002503
YPZhang240842b2016-05-17 12:00:50 -07002504 except AssertionError:
2505 main.log.exception( "" )
2506 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002507 except pexpect.TIMEOUT:
2508 main.log.error( self.name + ": ONOS timeout" )
2509 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002510 except pexpect.EOF:
2511 main.log.error( self.name + ": EOF exception found" )
2512 main.log.error( self.name + ": " + self.handle.before )
2513 main.cleanup()
2514 main.exit()
2515 except Exception:
2516 main.log.exception( self.name + ": Uncaught exception!" )
2517 main.cleanup()
2518 main.exit()
2519
GlennRCed771242016-01-13 17:02:47 -08002520 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002521 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002522 """
andrewonlab87852b02014-11-19 18:44:19 -05002523 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002524 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002525 a specific point-to-point intent definition
2526 Required:
GlennRCed771242016-01-13 17:02:47 -08002527 * ingress: specify source dpid
2528 * egress: specify destination dpid
2529 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002530 Optional:
GlennRCed771242016-01-13 17:02:47 -08002531 * offset: the keyOffset is where the next batch of intents
2532 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002533 * noExit: If set to True, TestON will not exit if any error when issus command
2534 * getResponse: If set to True, function will return ONOS response.
2535
GlennRCed771242016-01-13 17:02:47 -08002536 Returns: If failed to push test intents, it will returen None,
2537 if successful, return true.
2538 Timeout expection will return None,
2539 TypeError will return false
2540 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002541 """
andrewonlab87852b02014-11-19 18:44:19 -05002542 try:
GlennRCed771242016-01-13 17:02:47 -08002543 if background:
2544 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002545 else:
GlennRCed771242016-01-13 17:02:47 -08002546 back = ""
2547 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002548 ingress,
2549 egress,
2550 batchSize,
2551 offset,
2552 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002553 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002554 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002555 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002556 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002557 if getResponse:
2558 return response
2559
GlennRCed771242016-01-13 17:02:47 -08002560 # TODO: We should handle if there is failure in installation
2561 return main.TRUE
2562
Jon Hallc6793552016-01-19 14:18:37 -08002563 except AssertionError:
2564 main.log.exception( "" )
2565 return None
GlennRCed771242016-01-13 17:02:47 -08002566 except pexpect.TIMEOUT:
2567 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002568 return None
andrewonlab87852b02014-11-19 18:44:19 -05002569 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002572 main.cleanup()
2573 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002574 except TypeError:
2575 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002576 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002577 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002578 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002579 main.cleanup()
2580 main.exit()
2581
YPZhangebf9eb52016-05-12 15:20:24 -07002582 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002583 """
2584 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002585 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002586 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002587 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002588 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002589 """
YPZhange3109a72016-02-02 11:25:37 -08002590
YPZhangb5d3f832016-01-23 22:54:26 -08002591 try:
YPZhange3109a72016-02-02 11:25:37 -08002592 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002593 cmd = "flows -c added"
2594 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2595 if rawFlows:
2596 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002597 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002598 for l in rawFlows:
2599 totalFlows += int(l.split("Count=")[1])
2600 else:
2601 main.log.error("Response not as expected!")
2602 return None
2603 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002604
You Wangd3cb2ce2016-05-16 14:01:24 -07002605 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002606 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002607 return None
2608 except pexpect.EOF:
2609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002611 if not noExit:
2612 main.cleanup()
2613 main.exit()
2614 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002615 except pexpect.TIMEOUT:
2616 main.log.error( self.name + ": ONOS timeout" )
2617 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002618 except Exception:
2619 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002620 if not noExit:
2621 main.cleanup()
2622 main.exit()
2623 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002624
YPZhang14a4aa92016-07-15 13:37:15 -07002625 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002626 """
2627 Description:
2628 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002629 Optional:
2630 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002631 Return:
2632 The number of intents
2633 """
2634 try:
2635 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002636 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002637 if response is None:
2638 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002639 response = json.loads( response )
2640 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002641 except ( TypeError, ValueError ):
2642 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002643 return None
2644 except pexpect.EOF:
2645 main.log.error( self.name + ": EOF exception found" )
2646 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002647 if noExit:
2648 return -1
2649 else:
2650 main.cleanup()
2651 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002652 except Exception:
2653 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002654 if noExit:
2655 return -1
2656 else:
2657 main.cleanup()
2658 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002659
kelvin-onlabd3b64892015-01-20 13:26:24 -08002660 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002661 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002662 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002663 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002664 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002665 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002666 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002667 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002668 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002669 cmdStr += " -j"
2670 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002671 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002672 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002673 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002674 except AssertionError:
2675 main.log.exception( "" )
2676 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002677 except TypeError:
2678 main.log.exception( self.name + ": Object not as expected" )
2679 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002680 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002681 main.log.error( self.name + ": EOF exception found" )
2682 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002683 main.cleanup()
2684 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002685 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002686 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002687 main.cleanup()
2688 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002689
kelvin-onlabd3b64892015-01-20 13:26:24 -08002690 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002691 """
2692 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002693 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002694 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002695 """
andrewonlab867212a2014-10-22 20:13:38 -04002696 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002697 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002699 cmdStr += " -j"
2700 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002701 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002702 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002703 if handle:
2704 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002705 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002706 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002707 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002708 else:
2709 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002710 except AssertionError:
2711 main.log.exception( "" )
2712 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002713 except TypeError:
2714 main.log.exception( self.name + ": Object not as expected" )
2715 return None
andrewonlab867212a2014-10-22 20:13:38 -04002716 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002717 main.log.error( self.name + ": EOF exception found" )
2718 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002719 main.cleanup()
2720 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002721 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002722 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002723 main.cleanup()
2724 main.exit()
2725
kelvin8ec71442015-01-15 16:57:00 -08002726 # Wrapper functions ****************
2727 # Wrapper functions use existing driver
2728 # functions and extends their use case.
2729 # For example, we may use the output of
2730 # a normal driver function, and parse it
2731 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002732
kelvin-onlabd3b64892015-01-20 13:26:24 -08002733 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002734 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002735 Description:
2736 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002737 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002738 try:
kelvin8ec71442015-01-15 16:57:00 -08002739 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002740 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002741 if intentsStr is None:
2742 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002743 # Convert to a dictionary
2744 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002745 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002746 for intent in intents:
2747 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002748 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002749 except TypeError:
2750 main.log.exception( self.name + ": Object not as expected" )
2751 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002753 main.log.error( self.name + ": EOF exception found" )
2754 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002755 main.cleanup()
2756 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002757 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002758 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002759 main.cleanup()
2760 main.exit()
2761
You Wang3c276252016-09-21 15:21:36 -07002762 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002763 """
2764 Determine the number of flow rules for the given device id that are
2765 in the added state
You Wang3c276252016-09-21 15:21:36 -07002766 Params:
2767 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002768 """
2769 try:
You Wang3c276252016-09-21 15:21:36 -07002770 if core:
2771 cmdStr = "flows any " + str( deviceId ) + " | " +\
2772 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2773 else:
2774 cmdStr = "flows any " + str( deviceId ) + " | " +\
2775 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002776 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002777 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002778 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002779 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002780 except AssertionError:
2781 main.log.exception( "" )
2782 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002783 except pexpect.EOF:
2784 main.log.error( self.name + ": EOF exception found" )
2785 main.log.error( self.name + ": " + self.handle.before )
2786 main.cleanup()
2787 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002788 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002789 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002790 main.cleanup()
2791 main.exit()
2792
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002794 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002795 Use 'devices' function to obtain list of all devices
2796 and parse the result to obtain a list of all device
2797 id's. Returns this list. Returns empty list if no
2798 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002799 List is ordered sequentially
2800
andrewonlab3e15ead2014-10-15 14:21:34 -04002801 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002802 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002803 the ids. By obtaining the list of device ids on the fly,
2804 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002805 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002806 try:
kelvin8ec71442015-01-15 16:57:00 -08002807 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002808 devicesStr = self.devices( jsonFormat=False )
2809 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002810
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002812 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 return idList
kelvin8ec71442015-01-15 16:57:00 -08002814
2815 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002817 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002818 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002819 # Split list further into arguments before and after string
2820 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 # append to idList
2822 for arg in tempList:
2823 idList.append( arg.split( "id=" )[ 1 ] )
2824 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002825
Jon Halld4d4b372015-01-28 16:02:41 -08002826 except TypeError:
2827 main.log.exception( self.name + ": Object not as expected" )
2828 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002829 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002830 main.log.error( self.name + ": EOF exception found" )
2831 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002832 main.cleanup()
2833 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002834 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002835 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002836 main.cleanup()
2837 main.exit()
2838
kelvin-onlabd3b64892015-01-20 13:26:24 -08002839 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002840 """
andrewonlab7c211572014-10-15 16:45:20 -04002841 Uses 'nodes' function to obtain list of all nodes
2842 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002843 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002844 Returns:
2845 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002846 """
andrewonlab7c211572014-10-15 16:45:20 -04002847 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002848 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002850 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002851 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002852 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002853 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002854 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002855 nodesJson = json.loads( nodesStr )
2856 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002857 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002858 except ( TypeError, ValueError ):
2859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002860 return None
andrewonlab7c211572014-10-15 16:45:20 -04002861 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002864 main.cleanup()
2865 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002867 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002868 main.cleanup()
2869 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002870
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002872 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002873 Return the first device from the devices api whose 'id' contains 'dpid'
2874 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002875 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002876 try:
kelvin8ec71442015-01-15 16:57:00 -08002877 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002878 return None
2879 else:
kelvin8ec71442015-01-15 16:57:00 -08002880 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002881 rawDevices = self.devices()
2882 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002883 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002884 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002885 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2886 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002887 return device
2888 return None
Jon Hallc6793552016-01-19 14:18:37 -08002889 except ( TypeError, ValueError ):
2890 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002891 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002892 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002893 main.log.error( self.name + ": EOF exception found" )
2894 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002895 main.cleanup()
2896 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002898 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002899 main.cleanup()
2900 main.exit()
2901
You Wang24139872016-05-03 11:48:47 -07002902 def getTopology( self, topologyOutput ):
2903 """
2904 Definition:
2905 Loads a json topology output
2906 Return:
2907 topology = current ONOS topology
2908 """
2909 import json
2910 try:
2911 # either onos:topology or 'topology' will work in CLI
2912 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002913 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002914 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002915 except ( TypeError, ValueError ):
2916 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2917 return None
You Wang24139872016-05-03 11:48:47 -07002918 except pexpect.EOF:
2919 main.log.error( self.name + ": EOF exception found" )
2920 main.log.error( self.name + ": " + self.handle.before )
2921 main.cleanup()
2922 main.exit()
2923 except Exception:
2924 main.log.exception( self.name + ": Uncaught exception!" )
2925 main.cleanup()
2926 main.exit()
2927
Flavio Castro82ee2f62016-06-07 15:04:12 -07002928 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002929 """
Jon Hallefbd9792015-03-05 16:11:36 -08002930 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002931 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002932 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002933
Flavio Castro82ee2f62016-06-07 15:04:12 -07002934 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002935 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002936 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002937 logLevel = level to log to.
2938 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002939
Jon Hallefbd9792015-03-05 16:11:36 -08002940 Returns: main.TRUE if the number of switches and links are correct,
2941 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002942 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002943 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002944 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002945 try:
You Wang13310252016-07-31 10:56:14 -07002946 summary = self.summary()
2947 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002948 except ( TypeError, ValueError ):
2949 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2950 return main.ERROR
2951 try:
2952 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002953 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002954 return main.ERROR
2955 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002956 # Is the number of switches is what we expected
2957 devices = topology.get( 'devices', False )
2958 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002959 nodes = summary.get( 'nodes', False )
2960 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002961 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002962 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002963 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002964 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002965 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2966 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002967 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002968 output = output + "The number of links and switches match "\
2969 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002970 result = main.TRUE
2971 else:
You Wang24139872016-05-03 11:48:47 -07002972 output = output + \
2973 "The number of links and switches does not match " + \
2974 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002975 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002976 output = output + "\n ONOS sees %i devices" % int( devices )
2977 output = output + " (%i expected) " % int( numoswitch )
2978 output = output + "and %i links " % int( links )
2979 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002980 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002981 output = output + "and %i controllers " % int( nodes )
2982 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002983 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002984 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002986 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002987 else:
You Wang24139872016-05-03 11:48:47 -07002988 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002989 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002990 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002991 main.log.error( self.name + ": EOF exception found" )
2992 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002993 main.cleanup()
2994 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002995 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002996 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002997 main.cleanup()
2998 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002999
kelvin-onlabd3b64892015-01-20 13:26:24 -08003000 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003001 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003002 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003003 deviceId must be the id of a device as seen in the onos devices command
3004 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003005 role must be either master, standby, or none
3006
Jon Halle3f39ff2015-01-13 11:50:53 -08003007 Returns:
3008 main.TRUE or main.FALSE based on argument verification and
3009 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003010 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003011 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003012 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003013 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003014 cmdStr = "device-role " +\
3015 str( deviceId ) + " " +\
3016 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003017 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003018 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003019 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003020 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003021 if re.search( "Error", handle ):
3022 # end color output to escape any colours
3023 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003024 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003025 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003026 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003027 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003028 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003029 main.log.error( "Invalid 'role' given to device_role(). " +
3030 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003031 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003032 except AssertionError:
3033 main.log.exception( "" )
3034 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003035 except TypeError:
3036 main.log.exception( self.name + ": Object not as expected" )
3037 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003038 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003039 main.log.error( self.name + ": EOF exception found" )
3040 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003041 main.cleanup()
3042 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003043 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003044 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003045 main.cleanup()
3046 main.exit()
3047
kelvin-onlabd3b64892015-01-20 13:26:24 -08003048 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003049 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003050 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003051 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003052 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003053 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003054 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003055 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003056 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003057 cmdStr += " -j"
3058 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003059 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003060 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003061 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003062 except AssertionError:
3063 main.log.exception( "" )
3064 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003065 except TypeError:
3066 main.log.exception( self.name + ": Object not as expected" )
3067 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003068 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003069 main.log.error( self.name + ": EOF exception found" )
3070 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003071 main.cleanup()
3072 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003073 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003074 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003075 main.cleanup()
3076 main.exit()
3077
kelvin-onlabd3b64892015-01-20 13:26:24 -08003078 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003079 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003080 CLI command to get the current leader for the Election test application
3081 NOTE: Requires installation of the onos-app-election feature
3082 Returns: Node IP of the leader if one exists
3083 None if none exists
3084 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003085 """
Jon Hall94fd0472014-12-08 11:52:42 -08003086 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003087 cmdStr = "election-test-leader"
3088 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003089 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003090 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003091 # Leader
3092 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003093 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003094 nodeSearch = re.search( leaderPattern, response )
3095 if nodeSearch:
3096 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003097 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003098 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003099 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003100 # no leader
3101 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003102 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003103 nullSearch = re.search( nullPattern, response )
3104 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003105 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003106 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003107 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003108 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003109 main.log.error( "Error in electionTestLeader on " + self.name +
3110 ": " + "unexpected response" )
3111 main.log.error( repr( response ) )
3112 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003113 except AssertionError:
3114 main.log.exception( "" )
3115 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003116 except TypeError:
3117 main.log.exception( self.name + ": Object not as expected" )
3118 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003119 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003120 main.log.error( self.name + ": EOF exception found" )
3121 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003122 main.cleanup()
3123 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003124 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003125 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003126 main.cleanup()
3127 main.exit()
3128
kelvin-onlabd3b64892015-01-20 13:26:24 -08003129 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003130 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003131 CLI command to run for leadership of the Election test application.
3132 NOTE: Requires installation of the onos-app-election feature
3133 Returns: Main.TRUE on success
3134 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003135 """
Jon Hall94fd0472014-12-08 11:52:42 -08003136 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003137 cmdStr = "election-test-run"
3138 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003139 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003140 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003143 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003144 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003145 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003146 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003147 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003148 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003149 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003150 main.log.error( "Error in electionTestRun on " + self.name +
3151 ": " + "unexpected response" )
3152 main.log.error( repr( response ) )
3153 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003154 except AssertionError:
3155 main.log.exception( "" )
3156 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003163 main.cleanup()
3164 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003165 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003166 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003167 main.cleanup()
3168 main.exit()
3169
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003171 """
Jon Hall94fd0472014-12-08 11:52:42 -08003172 * CLI command to withdraw the local node from leadership election for
3173 * the Election test application.
3174 #NOTE: Requires installation of the onos-app-election feature
3175 Returns: Main.TRUE on success
3176 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003177 """
Jon Hall94fd0472014-12-08 11:52:42 -08003178 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003179 cmdStr = "election-test-withdraw"
3180 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003181 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003182 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003183 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003184 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003185 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003186 if re.search( successPattern, response ):
3187 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003188 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003189 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003190 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003191 main.log.error( "Error in electionTestWithdraw on " +
3192 self.name + ": " + "unexpected response" )
3193 main.log.error( repr( response ) )
3194 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003195 except AssertionError:
3196 main.log.exception( "" )
3197 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003198 except TypeError:
3199 main.log.exception( self.name + ": Object not as expected" )
3200 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003202 main.log.error( self.name + ": EOF exception found" )
3203 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003204 main.cleanup()
3205 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003207 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003208 main.cleanup()
3209 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003210
kelvin8ec71442015-01-15 16:57:00 -08003211 def getDevicePortsEnabledCount( self, dpid ):
3212 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003213 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003214 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003215 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003216 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003217 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3218 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003219 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003220 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003221 if re.search( "No such device", output ):
3222 main.log.error( "Error in getting ports" )
3223 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003224 return output
Jon Hallc6793552016-01-19 14:18:37 -08003225 except AssertionError:
3226 main.log.exception( "" )
3227 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003228 except TypeError:
3229 main.log.exception( self.name + ": Object not as expected" )
3230 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003232 main.log.error( self.name + ": EOF exception found" )
3233 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003234 main.cleanup()
3235 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003236 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003237 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003238 main.cleanup()
3239 main.exit()
3240
kelvin8ec71442015-01-15 16:57:00 -08003241 def getDeviceLinksActiveCount( self, dpid ):
3242 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003243 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003244 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003245 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003246 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003247 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3248 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003249 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003250 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003251 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003252 main.log.error( "Error in getting ports " )
3253 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003254 return output
Jon Hallc6793552016-01-19 14:18:37 -08003255 except AssertionError:
3256 main.log.exception( "" )
3257 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003258 except TypeError:
3259 main.log.exception( self.name + ": Object not as expected" )
3260 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003261 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003262 main.log.error( self.name + ": EOF exception found" )
3263 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003264 main.cleanup()
3265 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003266 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003267 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003268 main.cleanup()
3269 main.exit()
3270
kelvin8ec71442015-01-15 16:57:00 -08003271 def getAllIntentIds( self ):
3272 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003273 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003274 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003275 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003276 cmdStr = "onos:intents | grep id="
3277 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003278 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003279 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003280 if re.search( "Error", output ):
3281 main.log.error( "Error in getting ports" )
3282 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003283 return output
Jon Hallc6793552016-01-19 14:18:37 -08003284 except AssertionError:
3285 main.log.exception( "" )
3286 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003287 except TypeError:
3288 main.log.exception( self.name + ": Object not as expected" )
3289 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003290 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003291 main.log.error( self.name + ": EOF exception found" )
3292 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003293 main.cleanup()
3294 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003295 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003296 main.log.exception( self.name + ": Uncaught exception!" )
3297 main.cleanup()
3298 main.exit()
3299
Jon Hall73509952015-02-24 16:42:56 -08003300 def intentSummary( self ):
3301 """
Jon Hallefbd9792015-03-05 16:11:36 -08003302 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003303 """
3304 try:
3305 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003306 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003307 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003308 states.append( intent.get( 'state', None ) )
3309 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003310 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003311 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003312 except ( TypeError, ValueError ):
3313 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003314 return None
3315 except pexpect.EOF:
3316 main.log.error( self.name + ": EOF exception found" )
3317 main.log.error( self.name + ": " + self.handle.before )
3318 main.cleanup()
3319 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003320 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003321 main.log.exception( self.name + ": Uncaught exception!" )
3322 main.cleanup()
3323 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003324
Jon Hall61282e32015-03-19 11:34:11 -07003325 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003326 """
3327 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003328 Optional argument:
3329 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003330 """
Jon Hall63604932015-02-26 17:09:50 -08003331 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003333 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003334 cmdStr += " -j"
3335 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003336 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003337 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003338 return output
Jon Hallc6793552016-01-19 14:18:37 -08003339 except AssertionError:
3340 main.log.exception( "" )
3341 return None
Jon Hall63604932015-02-26 17:09:50 -08003342 except TypeError:
3343 main.log.exception( self.name + ": Object not as expected" )
3344 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003345 except pexpect.EOF:
3346 main.log.error( self.name + ": EOF exception found" )
3347 main.log.error( self.name + ": " + self.handle.before )
3348 main.cleanup()
3349 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003350 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003351 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003352 main.cleanup()
3353 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003354
acsmarsa4a4d1e2015-07-10 16:01:24 -07003355 def leaderCandidates( self, jsonFormat=True ):
3356 """
3357 Returns the output of the leaders -c command.
3358 Optional argument:
3359 * jsonFormat - boolean indicating if you want output in json
3360 """
3361 try:
3362 cmdStr = "onos:leaders -c"
3363 if jsonFormat:
3364 cmdStr += " -j"
3365 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003366 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003367 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003368 return output
Jon Hallc6793552016-01-19 14:18:37 -08003369 except AssertionError:
3370 main.log.exception( "" )
3371 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003372 except TypeError:
3373 main.log.exception( self.name + ": Object not as expected" )
3374 return None
3375 except pexpect.EOF:
3376 main.log.error( self.name + ": EOF exception found" )
3377 main.log.error( self.name + ": " + self.handle.before )
3378 main.cleanup()
3379 main.exit()
3380 except Exception:
3381 main.log.exception( self.name + ": Uncaught exception!" )
3382 main.cleanup()
3383 main.exit()
3384
Jon Hallc6793552016-01-19 14:18:37 -08003385 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003386 """
3387 Returns a list in format [leader,candidate1,candidate2,...] for a given
3388 topic parameter and an empty list if the topic doesn't exist
3389 If no leader is elected leader in the returned list will be "none"
3390 Returns None if there is a type error processing the json object
3391 """
3392 try:
Jon Hall6e709752016-02-01 13:38:46 -08003393 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003394 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003395 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003396 assert "Command not found:" not in rawOutput, rawOutput
3397 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003398 results = []
3399 for dict in output:
3400 if dict["topic"] == topic:
3401 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003402 candidates = re.split( ", ", dict["candidates"][1:-1] )
3403 results.append( leader )
3404 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003405 return results
Jon Hallc6793552016-01-19 14:18:37 -08003406 except AssertionError:
3407 main.log.exception( "" )
3408 return None
3409 except ( TypeError, ValueError ):
3410 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003411 return None
3412 except pexpect.EOF:
3413 main.log.error( self.name + ": EOF exception found" )
3414 main.log.error( self.name + ": " + self.handle.before )
3415 main.cleanup()
3416 main.exit()
3417 except Exception:
3418 main.log.exception( self.name + ": Uncaught exception!" )
3419 main.cleanup()
3420 main.exit()
3421
Jon Hall61282e32015-03-19 11:34:11 -07003422 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003423 """
3424 Returns the output of the intent Pending map.
3425 """
Jon Hall63604932015-02-26 17:09:50 -08003426 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003427 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003428 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003429 cmdStr += " -j"
3430 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003431 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003432 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003433 return output
Jon Hallc6793552016-01-19 14:18:37 -08003434 except AssertionError:
3435 main.log.exception( "" )
3436 return None
Jon Hall63604932015-02-26 17:09:50 -08003437 except TypeError:
3438 main.log.exception( self.name + ": Object not as expected" )
3439 return None
3440 except pexpect.EOF:
3441 main.log.error( self.name + ": EOF exception found" )
3442 main.log.error( self.name + ": " + self.handle.before )
3443 main.cleanup()
3444 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003445 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003446 main.log.exception( self.name + ": Uncaught exception!" )
3447 main.cleanup()
3448 main.exit()
3449
Jon Hall2c8959e2016-12-16 12:17:34 -08003450 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003451 """
3452 Returns the output of the raft partitions command for ONOS.
3453 """
Jon Hall61282e32015-03-19 11:34:11 -07003454 # Sample JSON
3455 # {
3456 # "leader": "tcp://10.128.30.11:7238",
3457 # "members": [
3458 # "tcp://10.128.30.11:7238",
3459 # "tcp://10.128.30.17:7238",
3460 # "tcp://10.128.30.13:7238",
3461 # ],
3462 # "name": "p1",
3463 # "term": 3
3464 # },
Jon Hall63604932015-02-26 17:09:50 -08003465 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003466 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003467 if candidates:
3468 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003469 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003470 cmdStr += " -j"
3471 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003472 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003473 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003474 return output
Jon Hallc6793552016-01-19 14:18:37 -08003475 except AssertionError:
3476 main.log.exception( "" )
3477 return None
Jon Hall63604932015-02-26 17:09:50 -08003478 except TypeError:
3479 main.log.exception( self.name + ": Object not as expected" )
3480 return None
3481 except pexpect.EOF:
3482 main.log.error( self.name + ": EOF exception found" )
3483 main.log.error( self.name + ": " + self.handle.before )
3484 main.cleanup()
3485 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003486 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003487 main.log.exception( self.name + ": Uncaught exception!" )
3488 main.cleanup()
3489 main.exit()
3490
Jon Halle9f909e2016-09-23 10:43:12 -07003491 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003492 """
3493 Returns the output of the apps command for ONOS. This command lists
3494 information about installed ONOS applications
3495 """
3496 # Sample JSON object
3497 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3498 # "description":"ONOS OpenFlow protocol southbound providers",
3499 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3500 # "features":"[onos-openflow]","state":"ACTIVE"}]
3501 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003502 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003503 if summary:
3504 cmdStr += " -s"
3505 if active:
3506 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003507 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003508 cmdStr += " -j"
3509 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003510 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003511 assert "Command not found:" not in output, output
3512 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003513 return output
Jon Hallbe379602015-03-24 13:39:32 -07003514 # FIXME: look at specific exceptions/Errors
3515 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003516 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003517 return None
3518 except TypeError:
3519 main.log.exception( self.name + ": Object not as expected" )
3520 return None
3521 except pexpect.EOF:
3522 main.log.error( self.name + ": EOF exception found" )
3523 main.log.error( self.name + ": " + self.handle.before )
3524 main.cleanup()
3525 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003526 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003527 main.log.exception( self.name + ": Uncaught exception!" )
3528 main.cleanup()
3529 main.exit()
3530
Jon Hall146f1522015-03-24 15:33:24 -07003531 def appStatus( self, appName ):
3532 """
3533 Uses the onos:apps cli command to return the status of an application.
3534 Returns:
3535 "ACTIVE" - If app is installed and activated
3536 "INSTALLED" - If app is installed and deactivated
3537 "UNINSTALLED" - If app is not installed
3538 None - on error
3539 """
Jon Hall146f1522015-03-24 15:33:24 -07003540 try:
3541 if not isinstance( appName, types.StringType ):
3542 main.log.error( self.name + ".appStatus(): appName must be" +
3543 " a string" )
3544 return None
3545 output = self.apps( jsonFormat=True )
3546 appsJson = json.loads( output )
3547 state = None
3548 for app in appsJson:
3549 if appName == app.get('name'):
3550 state = app.get('state')
3551 break
3552 if state == "ACTIVE" or state == "INSTALLED":
3553 return state
3554 elif state is None:
3555 return "UNINSTALLED"
3556 elif state:
3557 main.log.error( "Unexpected state from 'onos:apps': " +
3558 str( state ) )
3559 return state
Jon Hallc6793552016-01-19 14:18:37 -08003560 except ( TypeError, ValueError ):
3561 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003562 return None
3563 except pexpect.EOF:
3564 main.log.error( self.name + ": EOF exception found" )
3565 main.log.error( self.name + ": " + self.handle.before )
3566 main.cleanup()
3567 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003568 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003569 main.log.exception( self.name + ": Uncaught exception!" )
3570 main.cleanup()
3571 main.exit()
3572
Jon Hallbe379602015-03-24 13:39:32 -07003573 def app( self, appName, option ):
3574 """
3575 Interacts with the app command for ONOS. This command manages
3576 application inventory.
3577 """
Jon Hallbe379602015-03-24 13:39:32 -07003578 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003579 # Validate argument types
3580 valid = True
3581 if not isinstance( appName, types.StringType ):
3582 main.log.error( self.name + ".app(): appName must be a " +
3583 "string" )
3584 valid = False
3585 if not isinstance( option, types.StringType ):
3586 main.log.error( self.name + ".app(): option must be a string" )
3587 valid = False
3588 if not valid:
3589 return main.FALSE
3590 # Validate Option
3591 option = option.lower()
3592 # NOTE: Install may become a valid option
3593 if option == "activate":
3594 pass
3595 elif option == "deactivate":
3596 pass
3597 elif option == "uninstall":
3598 pass
3599 else:
3600 # Invalid option
3601 main.log.error( "The ONOS app command argument only takes " +
3602 "the values: (activate|deactivate|uninstall)" +
3603 "; was given '" + option + "'")
3604 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003605 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003606 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003607 assert output is not None, "Error in sendline"
3608 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003609 if "Error executing command" in output:
3610 main.log.error( "Error in processing onos:app command: " +
3611 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003612 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003613 elif "No such application" in output:
3614 main.log.error( "The application '" + appName +
3615 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003616 return main.FALSE
3617 elif "Command not found:" in output:
3618 main.log.error( "Error in processing onos:app command: " +
3619 str( output ) )
3620 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003621 elif "Unsupported command:" in output:
3622 main.log.error( "Incorrect command given to 'app': " +
3623 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003624 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003625 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003626 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003627 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003628 except AssertionError:
3629 main.log.exception( self.name + ": AssertionError exception found" )
3630 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003631 except TypeError:
3632 main.log.exception( self.name + ": Object not as expected" )
3633 return main.ERROR
3634 except pexpect.EOF:
3635 main.log.error( self.name + ": EOF exception found" )
3636 main.log.error( self.name + ": " + self.handle.before )
3637 main.cleanup()
3638 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003639 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003640 main.log.exception( self.name + ": Uncaught exception!" )
3641 main.cleanup()
3642 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003643
Jon Hallbd16b922015-03-26 17:53:15 -07003644 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003645 """
3646 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003647 appName is the hierarchical app name, not the feature name
3648 If check is True, method will check the status of the app after the
3649 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003650 Returns main.TRUE if the command was successfully sent
3651 main.FALSE if the cli responded with an error or given
3652 incorrect input
3653 """
3654 try:
3655 if not isinstance( appName, types.StringType ):
3656 main.log.error( self.name + ".activateApp(): appName must be" +
3657 " a string" )
3658 return main.FALSE
3659 status = self.appStatus( appName )
3660 if status == "INSTALLED":
3661 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003662 if check and response == main.TRUE:
3663 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003664 status = self.appStatus( appName )
3665 if status == "ACTIVE":
3666 return main.TRUE
3667 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003668 main.log.debug( "The state of application " +
3669 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003670 time.sleep( 1 )
3671 return main.FALSE
3672 else: # not 'check' or command didn't succeed
3673 return response
Jon Hall146f1522015-03-24 15:33:24 -07003674 elif status == "ACTIVE":
3675 return main.TRUE
3676 elif status == "UNINSTALLED":
3677 main.log.error( self.name + ": Tried to activate the " +
3678 "application '" + appName + "' which is not " +
3679 "installed." )
3680 else:
3681 main.log.error( "Unexpected return value from appStatus: " +
3682 str( status ) )
3683 return main.ERROR
3684 except TypeError:
3685 main.log.exception( self.name + ": Object not as expected" )
3686 return main.ERROR
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
3690 main.cleanup()
3691 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003692 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003693 main.log.exception( self.name + ": Uncaught exception!" )
3694 main.cleanup()
3695 main.exit()
3696
Jon Hallbd16b922015-03-26 17:53:15 -07003697 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003698 """
3699 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003700 appName is the hierarchical app name, not the feature name
3701 If check is True, method will check the status of the app after the
3702 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003703 Returns main.TRUE if the command was successfully sent
3704 main.FALSE if the cli responded with an error or given
3705 incorrect input
3706 """
3707 try:
3708 if not isinstance( appName, types.StringType ):
3709 main.log.error( self.name + ".deactivateApp(): appName must " +
3710 "be a string" )
3711 return main.FALSE
3712 status = self.appStatus( appName )
3713 if status == "INSTALLED":
3714 return main.TRUE
3715 elif status == "ACTIVE":
3716 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003717 if check and response == main.TRUE:
3718 for i in range(10): # try 10 times then give up
3719 status = self.appStatus( appName )
3720 if status == "INSTALLED":
3721 return main.TRUE
3722 else:
3723 time.sleep( 1 )
3724 return main.FALSE
3725 else: # not check or command didn't succeed
3726 return response
Jon Hall146f1522015-03-24 15:33:24 -07003727 elif status == "UNINSTALLED":
3728 main.log.warn( self.name + ": Tried to deactivate the " +
3729 "application '" + appName + "' which is not " +
3730 "installed." )
3731 return main.TRUE
3732 else:
3733 main.log.error( "Unexpected return value from appStatus: " +
3734 str( status ) )
3735 return main.ERROR
3736 except TypeError:
3737 main.log.exception( self.name + ": Object not as expected" )
3738 return main.ERROR
3739 except pexpect.EOF:
3740 main.log.error( self.name + ": EOF exception found" )
3741 main.log.error( self.name + ": " + self.handle.before )
3742 main.cleanup()
3743 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003744 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003745 main.log.exception( self.name + ": Uncaught exception!" )
3746 main.cleanup()
3747 main.exit()
3748
Jon Hallbd16b922015-03-26 17:53:15 -07003749 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003750 """
3751 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003752 appName is the hierarchical app name, not the feature name
3753 If check is True, method will check the status of the app after the
3754 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003755 Returns main.TRUE if the command was successfully sent
3756 main.FALSE if the cli responded with an error or given
3757 incorrect input
3758 """
3759 # TODO: check with Thomas about the state machine for apps
3760 try:
3761 if not isinstance( appName, types.StringType ):
3762 main.log.error( self.name + ".uninstallApp(): appName must " +
3763 "be a string" )
3764 return main.FALSE
3765 status = self.appStatus( appName )
3766 if status == "INSTALLED":
3767 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003768 if check and response == main.TRUE:
3769 for i in range(10): # try 10 times then give up
3770 status = self.appStatus( appName )
3771 if status == "UNINSTALLED":
3772 return main.TRUE
3773 else:
3774 time.sleep( 1 )
3775 return main.FALSE
3776 else: # not check or command didn't succeed
3777 return response
Jon Hall146f1522015-03-24 15:33:24 -07003778 elif status == "ACTIVE":
3779 main.log.warn( self.name + ": Tried to uninstall the " +
3780 "application '" + appName + "' which is " +
3781 "currently active." )
3782 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003783 if check and response == main.TRUE:
3784 for i in range(10): # try 10 times then give up
3785 status = self.appStatus( appName )
3786 if status == "UNINSTALLED":
3787 return main.TRUE
3788 else:
3789 time.sleep( 1 )
3790 return main.FALSE
3791 else: # not check or command didn't succeed
3792 return response
Jon Hall146f1522015-03-24 15:33:24 -07003793 elif status == "UNINSTALLED":
3794 return main.TRUE
3795 else:
3796 main.log.error( "Unexpected return value from appStatus: " +
3797 str( status ) )
3798 return main.ERROR
3799 except TypeError:
3800 main.log.exception( self.name + ": Object not as expected" )
3801 return main.ERROR
3802 except pexpect.EOF:
3803 main.log.error( self.name + ": EOF exception found" )
3804 main.log.error( self.name + ": " + self.handle.before )
3805 main.cleanup()
3806 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003807 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003808 main.log.exception( self.name + ": Uncaught exception!" )
3809 main.cleanup()
3810 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003811
3812 def appIDs( self, jsonFormat=True ):
3813 """
3814 Show the mappings between app id and app names given by the 'app-ids'
3815 cli command
3816 """
3817 try:
3818 cmdStr = "app-ids"
3819 if jsonFormat:
3820 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003821 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003822 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003823 assert "Command not found:" not in output, output
3824 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003825 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003826 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003827 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003828 return None
3829 except TypeError:
3830 main.log.exception( self.name + ": Object not as expected" )
3831 return None
3832 except pexpect.EOF:
3833 main.log.error( self.name + ": EOF exception found" )
3834 main.log.error( self.name + ": " + self.handle.before )
3835 main.cleanup()
3836 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003837 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003838 main.log.exception( self.name + ": Uncaught exception!" )
3839 main.cleanup()
3840 main.exit()
3841
3842 def appToIDCheck( self ):
3843 """
3844 This method will check that each application's ID listed in 'apps' is
3845 the same as the ID listed in 'app-ids'. The check will also check that
3846 there are no duplicate IDs issued. Note that an app ID should be
3847 a globaly unique numerical identifier for app/app-like features. Once
3848 an ID is registered, the ID is never freed up so that if an app is
3849 reinstalled it will have the same ID.
3850
3851 Returns: main.TRUE if the check passes and
3852 main.FALSE if the check fails or
3853 main.ERROR if there is some error in processing the test
3854 """
3855 try:
Jon Hall390696c2015-05-05 17:13:41 -07003856 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003857 rawJson = self.appIDs( jsonFormat=True )
3858 if rawJson:
3859 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003860 else:
Jon Hallc6793552016-01-19 14:18:37 -08003861 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003862 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003863 rawJson = self.apps( jsonFormat=True )
3864 if rawJson:
3865 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003866 else:
Jon Hallc6793552016-01-19 14:18:37 -08003867 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003868 bail = True
3869 if bail:
3870 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003871 result = main.TRUE
3872 for app in apps:
3873 appID = app.get( 'id' )
3874 if appID is None:
3875 main.log.error( "Error parsing app: " + str( app ) )
3876 result = main.FALSE
3877 appName = app.get( 'name' )
3878 if appName is None:
3879 main.log.error( "Error parsing app: " + str( app ) )
3880 result = main.FALSE
3881 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003882 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003883 # main.log.debug( "Comparing " + str( app ) + " to " +
3884 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003885 if not current: # if ids doesn't have this id
3886 result = main.FALSE
3887 main.log.error( "'app-ids' does not have the ID for " +
3888 str( appName ) + " that apps does." )
3889 elif len( current ) > 1:
3890 # there is more than one app with this ID
3891 result = main.FALSE
3892 # We will log this later in the method
3893 elif not current[0][ 'name' ] == appName:
3894 currentName = current[0][ 'name' ]
3895 result = main.FALSE
3896 main.log.error( "'app-ids' has " + str( currentName ) +
3897 " registered under id:" + str( appID ) +
3898 " but 'apps' has " + str( appName ) )
3899 else:
3900 pass # id and name match!
3901 # now make sure that app-ids has no duplicates
3902 idsList = []
3903 namesList = []
3904 for item in ids:
3905 idsList.append( item[ 'id' ] )
3906 namesList.append( item[ 'name' ] )
3907 if len( idsList ) != len( set( idsList ) ) or\
3908 len( namesList ) != len( set( namesList ) ):
3909 main.log.error( "'app-ids' has some duplicate entries: \n"
3910 + json.dumps( ids,
3911 sort_keys=True,
3912 indent=4,
3913 separators=( ',', ': ' ) ) )
3914 result = main.FALSE
3915 return result
Jon Hallc6793552016-01-19 14:18:37 -08003916 except ( TypeError, ValueError ):
3917 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003918 return main.ERROR
3919 except pexpect.EOF:
3920 main.log.error( self.name + ": EOF exception found" )
3921 main.log.error( self.name + ": " + self.handle.before )
3922 main.cleanup()
3923 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003924 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003925 main.log.exception( self.name + ": Uncaught exception!" )
3926 main.cleanup()
3927 main.exit()
3928
Jon Hallfb760a02015-04-13 15:35:03 -07003929 def getCfg( self, component=None, propName=None, short=False,
3930 jsonFormat=True ):
3931 """
3932 Get configuration settings from onos cli
3933 Optional arguments:
3934 component - Optionally only list configurations for a specific
3935 component. If None, all components with configurations
3936 are displayed. Case Sensitive string.
3937 propName - If component is specified, propName option will show
3938 only this specific configuration from that component.
3939 Case Sensitive string.
3940 jsonFormat - Returns output as json. Note that this will override
3941 the short option
3942 short - Short, less verbose, version of configurations.
3943 This is overridden by the json option
3944 returns:
3945 Output from cli as a string or None on error
3946 """
3947 try:
3948 baseStr = "cfg"
3949 cmdStr = " get"
3950 componentStr = ""
3951 if component:
3952 componentStr += " " + component
3953 if propName:
3954 componentStr += " " + propName
3955 if jsonFormat:
3956 baseStr += " -j"
3957 elif short:
3958 baseStr += " -s"
3959 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003960 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003961 assert "Command not found:" not in output, output
3962 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003963 return output
3964 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003965 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003966 return None
3967 except TypeError:
3968 main.log.exception( self.name + ": Object not as expected" )
3969 return None
3970 except pexpect.EOF:
3971 main.log.error( self.name + ": EOF exception found" )
3972 main.log.error( self.name + ": " + self.handle.before )
3973 main.cleanup()
3974 main.exit()
3975 except Exception:
3976 main.log.exception( self.name + ": Uncaught exception!" )
3977 main.cleanup()
3978 main.exit()
3979
3980 def setCfg( self, component, propName, value=None, check=True ):
3981 """
3982 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003983 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003984 component - The case sensitive name of the component whose
3985 property is to be set
3986 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003987 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003988 value - The value to set the property to. If None, will unset the
3989 property and revert it to it's default value(if applicable)
3990 check - Boolean, Check whether the option was successfully set this
3991 only applies when a value is given.
3992 returns:
3993 main.TRUE on success or main.FALSE on failure. If check is False,
3994 will return main.TRUE unless there is an error
3995 """
3996 try:
3997 baseStr = "cfg"
3998 cmdStr = " set " + str( component ) + " " + str( propName )
3999 if value is not None:
4000 cmdStr += " " + str( value )
4001 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004002 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004003 assert "Command not found:" not in output, output
4004 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004005 if value and check:
4006 results = self.getCfg( component=str( component ),
4007 propName=str( propName ),
4008 jsonFormat=True )
4009 # Check if current value is what we just set
4010 try:
4011 jsonOutput = json.loads( results )
4012 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004013 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004014 main.log.exception( "Error parsing cfg output" )
4015 main.log.error( "output:" + repr( results ) )
4016 return main.FALSE
4017 if current == str( value ):
4018 return main.TRUE
4019 return main.FALSE
4020 return main.TRUE
4021 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004022 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004023 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004024 except ( TypeError, ValueError ):
4025 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004026 return main.FALSE
4027 except pexpect.EOF:
4028 main.log.error( self.name + ": EOF exception found" )
4029 main.log.error( self.name + ": " + self.handle.before )
4030 main.cleanup()
4031 main.exit()
4032 except Exception:
4033 main.log.exception( self.name + ": Uncaught exception!" )
4034 main.cleanup()
4035 main.exit()
4036
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004037 def distPrimitivesSend( self, cmd ):
4038 """
4039 Function to handle sending cli commands for the distributed primitives test app
4040
4041 This command will catch some exceptions and retry the command on some
4042 specific store exceptions.
4043
4044 Required arguments:
4045 cmd - The command to send to the cli
4046 returns:
4047 string containing the cli output
4048 None on Error
4049 """
4050 try:
4051 output = self.sendline( cmd )
4052 try:
4053 assert output is not None, "Error in sendline"
4054 # TODO: Maybe make this less hardcoded
4055 # ConsistentMap Exceptions
4056 assert "org.onosproject.store.service" not in output
4057 # Node not leader
4058 assert "java.lang.IllegalStateException" not in output
4059 except AssertionError:
4060 main.log.error( "Error in processing '" + cmd + "' " +
4061 "command: " + str( output ) )
4062 retryTime = 30 # Conservative time, given by Madan
4063 main.log.info( "Waiting " + str( retryTime ) +
4064 "seconds before retrying." )
4065 time.sleep( retryTime ) # Due to change in mastership
4066 output = self.sendline( cmd )
4067 assert output is not None, "Error in sendline"
4068 assert "Command not found:" not in output, output
4069 assert "Error executing command" not in output, output
4070 main.log.info( self.name + ": " + output )
4071 return output
4072 except AssertionError:
4073 main.log.exception( "Error in processing '" + cmd + "' command." )
4074 return None
4075 except TypeError:
4076 main.log.exception( self.name + ": Object not as expected" )
4077 return None
4078 except pexpect.EOF:
4079 main.log.error( self.name + ": EOF exception found" )
4080 main.log.error( self.name + ": " + self.handle.before )
4081 main.cleanup()
4082 main.exit()
4083 except Exception:
4084 main.log.exception( self.name + ": Uncaught exception!" )
4085 main.cleanup()
4086 main.exit()
4087
Jon Hall390696c2015-05-05 17:13:41 -07004088 def setTestAdd( self, setName, values ):
4089 """
4090 CLI command to add elements to a distributed set.
4091 Arguments:
4092 setName - The name of the set to add to.
4093 values - The value(s) to add to the set, space seperated.
4094 Example usages:
4095 setTestAdd( "set1", "a b c" )
4096 setTestAdd( "set2", "1" )
4097 returns:
4098 main.TRUE on success OR
4099 main.FALSE if elements were already in the set OR
4100 main.ERROR on error
4101 """
4102 try:
4103 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004104 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004105 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4106 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004107 if re.search( positiveMatch, output):
4108 return main.TRUE
4109 elif re.search( negativeMatch, output):
4110 return main.FALSE
4111 else:
4112 main.log.error( self.name + ": setTestAdd did not" +
4113 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004114 main.log.debug( self.name + " actual: " + repr( output ) )
4115 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004116 except TypeError:
4117 main.log.exception( self.name + ": Object not as expected" )
4118 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004119 except Exception:
4120 main.log.exception( self.name + ": Uncaught exception!" )
4121 main.cleanup()
4122 main.exit()
4123
4124 def setTestRemove( self, setName, values, clear=False, retain=False ):
4125 """
4126 CLI command to remove elements from a distributed set.
4127 Required arguments:
4128 setName - The name of the set to remove from.
4129 values - The value(s) to remove from the set, space seperated.
4130 Optional arguments:
4131 clear - Clear all elements from the set
4132 retain - Retain only the given values. (intersection of the
4133 original set and the given set)
4134 returns:
4135 main.TRUE on success OR
4136 main.FALSE if the set was not changed OR
4137 main.ERROR on error
4138 """
4139 try:
4140 cmdStr = "set-test-remove "
4141 if clear:
4142 cmdStr += "-c " + str( setName )
4143 elif retain:
4144 cmdStr += "-r " + str( setName ) + " " + str( values )
4145 else:
4146 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004147 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004148 if clear:
4149 pattern = "Set " + str( setName ) + " cleared"
4150 if re.search( pattern, output ):
4151 return main.TRUE
4152 elif retain:
4153 positivePattern = str( setName ) + " was pruned to contain " +\
4154 "only elements of set \[(.*)\]"
4155 negativePattern = str( setName ) + " was not changed by " +\
4156 "retaining only elements of the set " +\
4157 "\[(.*)\]"
4158 if re.search( positivePattern, output ):
4159 return main.TRUE
4160 elif re.search( negativePattern, output ):
4161 return main.FALSE
4162 else:
4163 positivePattern = "\[(.*)\] was removed from the set " +\
4164 str( setName )
4165 if ( len( values.split() ) == 1 ):
4166 negativePattern = "\[(.*)\] was not in set " +\
4167 str( setName )
4168 else:
4169 negativePattern = "No element of \[(.*)\] was in set " +\
4170 str( setName )
4171 if re.search( positivePattern, output ):
4172 return main.TRUE
4173 elif re.search( negativePattern, output ):
4174 return main.FALSE
4175 main.log.error( self.name + ": setTestRemove did not" +
4176 " match expected output" )
4177 main.log.debug( self.name + " expected: " + pattern )
4178 main.log.debug( self.name + " actual: " + repr( output ) )
4179 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004180 except TypeError:
4181 main.log.exception( self.name + ": Object not as expected" )
4182 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004183 except Exception:
4184 main.log.exception( self.name + ": Uncaught exception!" )
4185 main.cleanup()
4186 main.exit()
4187
4188 def setTestGet( self, setName, values="" ):
4189 """
4190 CLI command to get the elements in a distributed set.
4191 Required arguments:
4192 setName - The name of the set to remove from.
4193 Optional arguments:
4194 values - The value(s) to check if in the set, space seperated.
4195 returns:
4196 main.ERROR on error OR
4197 A list of elements in the set if no optional arguments are
4198 supplied OR
4199 A tuple containing the list then:
4200 main.FALSE if the given values are not in the set OR
4201 main.TRUE if the given values are in the set OR
4202 """
4203 try:
4204 values = str( values ).strip()
4205 setName = str( setName ).strip()
4206 length = len( values.split() )
4207 containsCheck = None
4208 # Patterns to match
4209 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004210 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004211 containsTrue = "Set " + setName + " contains the value " + values
4212 containsFalse = "Set " + setName + " did not contain the value " +\
4213 values
4214 containsAllTrue = "Set " + setName + " contains the the subset " +\
4215 setPattern
4216 containsAllFalse = "Set " + setName + " did not contain the the" +\
4217 " subset " + setPattern
4218
4219 cmdStr = "set-test-get "
4220 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004221 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004222 if length == 0:
4223 match = re.search( pattern, output )
4224 else: # if given values
4225 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004226 patternTrue = pattern + "\r\n" + containsTrue
4227 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004228 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004229 patternTrue = pattern + "\r\n" + containsAllTrue
4230 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004231 matchTrue = re.search( patternTrue, output )
4232 matchFalse = re.search( patternFalse, output )
4233 if matchTrue:
4234 containsCheck = main.TRUE
4235 match = matchTrue
4236 elif matchFalse:
4237 containsCheck = main.FALSE
4238 match = matchFalse
4239 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004240 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004241 "expected output" )
4242 main.log.debug( self.name + " expected: " + pattern )
4243 main.log.debug( self.name + " actual: " + repr( output ) )
4244 match = None
4245 if match:
4246 setMatch = match.group( 1 )
4247 if setMatch == '':
4248 setList = []
4249 else:
4250 setList = setMatch.split( ", " )
4251 if length > 0:
4252 return ( setList, containsCheck )
4253 else:
4254 return setList
4255 else: # no match
4256 main.log.error( self.name + ": setTestGet did not" +
4257 " match expected output" )
4258 main.log.debug( self.name + " expected: " + pattern )
4259 main.log.debug( self.name + " actual: " + repr( output ) )
4260 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004261 except TypeError:
4262 main.log.exception( self.name + ": Object not as expected" )
4263 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004264 except Exception:
4265 main.log.exception( self.name + ": Uncaught exception!" )
4266 main.cleanup()
4267 main.exit()
4268
4269 def setTestSize( self, setName ):
4270 """
4271 CLI command to get the elements in a distributed set.
4272 Required arguments:
4273 setName - The name of the set to remove from.
4274 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004275 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004276 None on error
4277 """
4278 try:
4279 # TODO: Should this check against the number of elements returned
4280 # and then return true/false based on that?
4281 setName = str( setName ).strip()
4282 # Patterns to match
4283 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004284 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004285 setPattern
4286 cmdStr = "set-test-get -s "
4287 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004288 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004289 match = re.search( pattern, output )
4290 if match:
4291 setSize = int( match.group( 1 ) )
4292 setMatch = match.group( 2 )
4293 if len( setMatch.split() ) == setSize:
4294 main.log.info( "The size returned by " + self.name +
4295 " matches the number of elements in " +
4296 "the returned set" )
4297 else:
4298 main.log.error( "The size returned by " + self.name +
4299 " does not match the number of " +
4300 "elements in the returned set." )
4301 return setSize
4302 else: # no match
4303 main.log.error( self.name + ": setTestGet did not" +
4304 " match expected output" )
4305 main.log.debug( self.name + " expected: " + pattern )
4306 main.log.debug( self.name + " actual: " + repr( output ) )
4307 return None
Jon Hall390696c2015-05-05 17:13:41 -07004308 except TypeError:
4309 main.log.exception( self.name + ": Object not as expected" )
4310 return None
Jon Hall390696c2015-05-05 17:13:41 -07004311 except Exception:
4312 main.log.exception( self.name + ": Uncaught exception!" )
4313 main.cleanup()
4314 main.exit()
4315
Jon Hall80daded2015-05-27 16:07:00 -07004316 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004317 """
4318 Command to list the various counters in the system.
4319 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004320 if jsonFormat, a string of the json object returned by the cli
4321 command
4322 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004323 None on error
4324 """
Jon Hall390696c2015-05-05 17:13:41 -07004325 try:
Jon Hall390696c2015-05-05 17:13:41 -07004326 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004327 if jsonFormat:
4328 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004329 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004330 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004331 assert "Command not found:" not in output, output
4332 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004333 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004334 return output
Jon Hall390696c2015-05-05 17:13:41 -07004335 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004336 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004337 return None
Jon Hall390696c2015-05-05 17:13:41 -07004338 except TypeError:
4339 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004340 return None
Jon Hall390696c2015-05-05 17:13:41 -07004341 except pexpect.EOF:
4342 main.log.error( self.name + ": EOF exception found" )
4343 main.log.error( self.name + ": " + self.handle.before )
4344 main.cleanup()
4345 main.exit()
4346 except Exception:
4347 main.log.exception( self.name + ": Uncaught exception!" )
4348 main.cleanup()
4349 main.exit()
4350
Jon Hall935db192016-04-19 00:22:04 -07004351 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004352 """
Jon Halle1a3b752015-07-22 13:02:46 -07004353 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004354 Required arguments:
4355 counter - The name of the counter to increment.
4356 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004357 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004358 returns:
4359 integer value of the counter or
4360 None on Error
4361 """
4362 try:
4363 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004364 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004365 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004366 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004367 if delta != 1:
4368 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004369 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004370 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004371 match = re.search( pattern, output )
4372 if match:
4373 return int( match.group( 1 ) )
4374 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004375 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004376 " match expected output." )
4377 main.log.debug( self.name + " expected: " + pattern )
4378 main.log.debug( self.name + " actual: " + repr( output ) )
4379 return None
Jon Hall390696c2015-05-05 17:13:41 -07004380 except TypeError:
4381 main.log.exception( self.name + ": Object not as expected" )
4382 return None
Jon Hall390696c2015-05-05 17:13:41 -07004383 except Exception:
4384 main.log.exception( self.name + ": Uncaught exception!" )
4385 main.cleanup()
4386 main.exit()
4387
Jon Hall935db192016-04-19 00:22:04 -07004388 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004389 """
4390 CLI command to get a distributed counter then add a delta to it.
4391 Required arguments:
4392 counter - The name of the counter to increment.
4393 Optional arguments:
4394 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004395 returns:
4396 integer value of the counter or
4397 None on Error
4398 """
4399 try:
4400 counter = str( counter )
4401 delta = int( delta )
4402 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004403 cmdStr += counter
4404 if delta != 1:
4405 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004406 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004407 pattern = counter + " was updated to (-?\d+)"
4408 match = re.search( pattern, output )
4409 if match:
4410 return int( match.group( 1 ) )
4411 else:
4412 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4413 " match expected output." )
4414 main.log.debug( self.name + " expected: " + pattern )
4415 main.log.debug( self.name + " actual: " + repr( output ) )
4416 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004417 except TypeError:
4418 main.log.exception( self.name + ": Object not as expected" )
4419 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004420 except Exception:
4421 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004422 main.cleanup()
4423 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004424
4425 def valueTestGet( self, valueName ):
4426 """
4427 CLI command to get the value of an atomic value.
4428 Required arguments:
4429 valueName - The name of the value to get.
4430 returns:
4431 string value of the value or
4432 None on Error
4433 """
4434 try:
4435 valueName = str( valueName )
4436 cmdStr = "value-test "
4437 operation = "get"
4438 cmdStr = "value-test {} {}".format( valueName,
4439 operation )
4440 output = self.distPrimitivesSend( cmdStr )
4441 pattern = "(\w+)"
4442 match = re.search( pattern, output )
4443 if match:
4444 return match.group( 1 )
4445 else:
4446 main.log.error( self.name + ": valueTestGet did not" +
4447 " match expected output." )
4448 main.log.debug( self.name + " expected: " + pattern )
4449 main.log.debug( self.name + " actual: " + repr( output ) )
4450 return None
4451 except TypeError:
4452 main.log.exception( self.name + ": Object not as expected" )
4453 return None
4454 except Exception:
4455 main.log.exception( self.name + ": Uncaught exception!" )
4456 main.cleanup()
4457 main.exit()
4458
4459 def valueTestSet( self, valueName, newValue ):
4460 """
4461 CLI command to set the value of an atomic value.
4462 Required arguments:
4463 valueName - The name of the value to set.
4464 newValue - The value to assign to the given value.
4465 returns:
4466 main.TRUE on success or
4467 main.ERROR on Error
4468 """
4469 try:
4470 valueName = str( valueName )
4471 newValue = str( newValue )
4472 operation = "set"
4473 cmdStr = "value-test {} {} {}".format( valueName,
4474 operation,
4475 newValue )
4476 output = self.distPrimitivesSend( cmdStr )
4477 if output is not None:
4478 return main.TRUE
4479 else:
4480 return main.ERROR
4481 except TypeError:
4482 main.log.exception( self.name + ": Object not as expected" )
4483 return main.ERROR
4484 except Exception:
4485 main.log.exception( self.name + ": Uncaught exception!" )
4486 main.cleanup()
4487 main.exit()
4488
4489 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4490 """
4491 CLI command to compareAndSet the value of an atomic value.
4492 Required arguments:
4493 valueName - The name of the value.
4494 oldValue - Compare the current value of the atomic value to this
4495 newValue - If the value equals oldValue, set the value to newValue
4496 returns:
4497 main.TRUE on success or
4498 main.FALSE on failure or
4499 main.ERROR on Error
4500 """
4501 try:
4502 valueName = str( valueName )
4503 oldValue = str( oldValue )
4504 newValue = str( newValue )
4505 operation = "compareAndSet"
4506 cmdStr = "value-test {} {} {} {}".format( valueName,
4507 operation,
4508 oldValue,
4509 newValue )
4510 output = self.distPrimitivesSend( cmdStr )
4511 pattern = "(\w+)"
4512 match = re.search( pattern, output )
4513 if match:
4514 result = match.group( 1 )
4515 if result == "true":
4516 return main.TRUE
4517 elif result == "false":
4518 return main.FALSE
4519 else:
4520 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4521 " match expected output." )
4522 main.log.debug( self.name + " expected: " + pattern )
4523 main.log.debug( self.name + " actual: " + repr( output ) )
4524 return main.ERROR
4525 except TypeError:
4526 main.log.exception( self.name + ": Object not as expected" )
4527 return main.ERROR
4528 except Exception:
4529 main.log.exception( self.name + ": Uncaught exception!" )
4530 main.cleanup()
4531 main.exit()
4532
4533 def valueTestGetAndSet( self, valueName, newValue ):
4534 """
4535 CLI command to getAndSet the value of an atomic value.
4536 Required arguments:
4537 valueName - The name of the value to get.
4538 newValue - The value to assign to the given value
4539 returns:
4540 string value of the value or
4541 None on Error
4542 """
4543 try:
4544 valueName = str( valueName )
4545 cmdStr = "value-test "
4546 operation = "getAndSet"
4547 cmdStr += valueName + " " + operation
4548 cmdStr = "value-test {} {} {}".format( valueName,
4549 operation,
4550 newValue )
4551 output = self.distPrimitivesSend( cmdStr )
4552 pattern = "(\w+)"
4553 match = re.search( pattern, output )
4554 if match:
4555 return match.group( 1 )
4556 else:
4557 main.log.error( self.name + ": valueTestGetAndSet did not" +
4558 " match expected output." )
4559 main.log.debug( self.name + " expected: " + pattern )
4560 main.log.debug( self.name + " actual: " + repr( output ) )
4561 return None
4562 except TypeError:
4563 main.log.exception( self.name + ": Object not as expected" )
4564 return None
4565 except Exception:
4566 main.log.exception( self.name + ": Uncaught exception!" )
4567 main.cleanup()
4568 main.exit()
4569
4570 def valueTestDestroy( self, valueName ):
4571 """
4572 CLI command to destroy an atomic value.
4573 Required arguments:
4574 valueName - The name of the value to destroy.
4575 returns:
4576 main.TRUE on success or
4577 main.ERROR on Error
4578 """
4579 try:
4580 valueName = str( valueName )
4581 cmdStr = "value-test "
4582 operation = "destroy"
4583 cmdStr += valueName + " " + operation
4584 output = self.distPrimitivesSend( cmdStr )
4585 if output is not None:
4586 return main.TRUE
4587 else:
4588 return main.ERROR
4589 except TypeError:
4590 main.log.exception( self.name + ": Object not as expected" )
4591 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004592 except Exception:
4593 main.log.exception( self.name + ": Uncaught exception!" )
4594 main.cleanup()
4595 main.exit()
4596
YPZhangfebf7302016-05-24 16:45:56 -07004597 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004598 """
4599 Description: Execute summary command in onos
4600 Returns: json object ( summary -j ), returns main.FALSE if there is
4601 no output
4602
4603 """
4604 try:
4605 cmdStr = "summary"
4606 if jsonFormat:
4607 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004608 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004609 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004610 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004611 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004612 if not handle:
4613 main.log.error( self.name + ": There is no output in " +
4614 "summary command" )
4615 return main.FALSE
4616 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004617 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004618 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004619 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004620 except TypeError:
4621 main.log.exception( self.name + ": Object not as expected" )
4622 return None
4623 except pexpect.EOF:
4624 main.log.error( self.name + ": EOF exception found" )
4625 main.log.error( self.name + ": " + self.handle.before )
4626 main.cleanup()
4627 main.exit()
4628 except Exception:
4629 main.log.exception( self.name + ": Uncaught exception!" )
4630 main.cleanup()
4631 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004632
Jon Hall935db192016-04-19 00:22:04 -07004633 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004634 """
4635 CLI command to get the value of a key in a consistent map using
4636 transactions. This a test function and can only get keys from the
4637 test map hard coded into the cli command
4638 Required arguments:
4639 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004640 returns:
4641 The string value of the key or
4642 None on Error
4643 """
4644 try:
4645 keyName = str( keyName )
4646 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004647 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004648 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004649 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4650 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004651 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004652 return None
4653 else:
4654 match = re.search( pattern, output )
4655 if match:
4656 return match.groupdict()[ 'value' ]
4657 else:
4658 main.log.error( self.name + ": transactionlMapGet did not" +
4659 " match expected output." )
4660 main.log.debug( self.name + " expected: " + pattern )
4661 main.log.debug( self.name + " actual: " + repr( output ) )
4662 return None
4663 except TypeError:
4664 main.log.exception( self.name + ": Object not as expected" )
4665 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004666 except Exception:
4667 main.log.exception( self.name + ": Uncaught exception!" )
4668 main.cleanup()
4669 main.exit()
4670
Jon Hall935db192016-04-19 00:22:04 -07004671 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004672 """
4673 CLI command to put a value into 'numKeys' number of keys in a
4674 consistent map using transactions. This a test function and can only
4675 put into keys named 'Key#' of the test map hard coded into the cli command
4676 Required arguments:
4677 numKeys - Number of keys to add the value to
4678 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004679 returns:
4680 A dictionary whose keys are the name of the keys put into the map
4681 and the values of the keys are dictionaries whose key-values are
4682 'value': value put into map and optionaly
4683 'oldValue': Previous value in the key or
4684 None on Error
4685
4686 Example output
4687 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4688 'Key2': {'value': 'Testing'} }
4689 """
4690 try:
4691 numKeys = str( numKeys )
4692 value = str( value )
4693 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004694 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004695 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004696 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4697 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4698 results = {}
4699 for line in output.splitlines():
4700 new = re.search( newPattern, line )
4701 updated = re.search( updatedPattern, line )
4702 if new:
4703 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4704 elif updated:
4705 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004706 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004707 else:
4708 main.log.error( self.name + ": transactionlMapGet did not" +
4709 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004710 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4711 newPattern,
4712 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004713 main.log.debug( self.name + " actual: " + repr( output ) )
4714 return results
4715 except TypeError:
4716 main.log.exception( self.name + ": Object not as expected" )
4717 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004718 except Exception:
4719 main.log.exception( self.name + ": Uncaught exception!" )
4720 main.cleanup()
4721 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004722
acsmarsdaea66c2015-09-03 11:44:06 -07004723 def maps( self, jsonFormat=True ):
4724 """
4725 Description: Returns result of onos:maps
4726 Optional:
4727 * jsonFormat: enable json formatting of output
4728 """
4729 try:
4730 cmdStr = "maps"
4731 if jsonFormat:
4732 cmdStr += " -j"
4733 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004734 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004735 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004736 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004737 except AssertionError:
4738 main.log.exception( "" )
4739 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004740 except TypeError:
4741 main.log.exception( self.name + ": Object not as expected" )
4742 return None
4743 except pexpect.EOF:
4744 main.log.error( self.name + ": EOF exception found" )
4745 main.log.error( self.name + ": " + self.handle.before )
4746 main.cleanup()
4747 main.exit()
4748 except Exception:
4749 main.log.exception( self.name + ": Uncaught exception!" )
4750 main.cleanup()
4751 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004752
4753 def getSwController( self, uri, jsonFormat=True ):
4754 """
4755 Descrition: Gets the controller information from the device
4756 """
4757 try:
4758 cmd = "device-controllers "
4759 if jsonFormat:
4760 cmd += "-j "
4761 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004762 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004763 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004764 return response
Jon Hallc6793552016-01-19 14:18:37 -08004765 except AssertionError:
4766 main.log.exception( "" )
4767 return None
GlennRC050596c2015-11-18 17:06:41 -08004768 except TypeError:
4769 main.log.exception( self.name + ": Object not as expected" )
4770 return None
4771 except pexpect.EOF:
4772 main.log.error( self.name + ": EOF exception found" )
4773 main.log.error( self.name + ": " + self.handle.before )
4774 main.cleanup()
4775 main.exit()
4776 except Exception:
4777 main.log.exception( self.name + ": Uncaught exception!" )
4778 main.cleanup()
4779 main.exit()
4780
4781 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4782 """
4783 Descrition: sets the controller(s) for the specified device
4784
4785 Parameters:
4786 Required: uri - String: The uri of the device(switch).
4787 ip - String or List: The ip address of the controller.
4788 This parameter can be formed in a couple of different ways.
4789 VALID:
4790 10.0.0.1 - just the ip address
4791 tcp:10.0.0.1 - the protocol and the ip address
4792 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4793 so that you can add controllers with different
4794 protocols and ports
4795 INVALID:
4796 10.0.0.1:6653 - this is not supported by ONOS
4797
4798 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4799 port - The port number.
4800 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4801
4802 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4803 """
4804 try:
4805 cmd = "device-setcontrollers"
4806
4807 if jsonFormat:
4808 cmd += " -j"
4809 cmd += " " + uri
4810 if isinstance( ip, str ):
4811 ip = [ip]
4812 for item in ip:
4813 if ":" in item:
4814 sitem = item.split( ":" )
4815 if len(sitem) == 3:
4816 cmd += " " + item
4817 elif "." in sitem[1]:
4818 cmd += " {}:{}".format(item, port)
4819 else:
4820 main.log.error( "Malformed entry: " + item )
4821 raise TypeError
4822 else:
4823 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004824 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004825 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004826 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004827 if "Error" in response:
4828 main.log.error( response )
4829 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004830 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004831 except AssertionError:
4832 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004833 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004834 except TypeError:
4835 main.log.exception( self.name + ": Object not as expected" )
4836 return main.FALSE
4837 except pexpect.EOF:
4838 main.log.error( self.name + ": EOF exception found" )
4839 main.log.error( self.name + ": " + self.handle.before )
4840 main.cleanup()
4841 main.exit()
4842 except Exception:
4843 main.log.exception( self.name + ": Uncaught exception!" )
4844 main.cleanup()
4845 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004846
4847 def removeDevice( self, device ):
4848 '''
4849 Description:
4850 Remove a device from ONOS by passing the uri of the device(s).
4851 Parameters:
4852 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4853 Returns:
4854 Returns main.FALSE if an exception is thrown or an error is present
4855 in the response. Otherwise, returns main.TRUE.
4856 NOTE:
4857 If a host cannot be removed, then this function will return main.FALSE
4858 '''
4859 try:
4860 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004861 deviceStr = device
4862 device = []
4863 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004864
4865 for d in device:
4866 time.sleep( 1 )
4867 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004868 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004869 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004870 if "Error" in response:
4871 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4872 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004873 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004874 except AssertionError:
4875 main.log.exception( "" )
4876 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004877 except TypeError:
4878 main.log.exception( self.name + ": Object not as expected" )
4879 return main.FALSE
4880 except pexpect.EOF:
4881 main.log.error( self.name + ": EOF exception found" )
4882 main.log.error( self.name + ": " + self.handle.before )
4883 main.cleanup()
4884 main.exit()
4885 except Exception:
4886 main.log.exception( self.name + ": Uncaught exception!" )
4887 main.cleanup()
4888 main.exit()
4889
4890 def removeHost( self, host ):
4891 '''
4892 Description:
4893 Remove a host from ONOS by passing the id of the host(s)
4894 Parameters:
4895 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4896 Returns:
4897 Returns main.FALSE if an exception is thrown or an error is present
4898 in the response. Otherwise, returns main.TRUE.
4899 NOTE:
4900 If a host cannot be removed, then this function will return main.FALSE
4901 '''
4902 try:
4903 if type( host ) is str:
4904 host = list( host )
4905
4906 for h in host:
4907 time.sleep( 1 )
4908 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004909 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004910 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004911 if "Error" in response:
4912 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4913 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004914 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004915 except AssertionError:
4916 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004917 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004918 except TypeError:
4919 main.log.exception( self.name + ": Object not as expected" )
4920 return main.FALSE
4921 except pexpect.EOF:
4922 main.log.error( self.name + ": EOF exception found" )
4923 main.log.error( self.name + ": " + self.handle.before )
4924 main.cleanup()
4925 main.exit()
4926 except Exception:
4927 main.log.exception( self.name + ": Uncaught exception!" )
4928 main.cleanup()
4929 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004930
YPZhangfebf7302016-05-24 16:45:56 -07004931 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004932 '''
4933 Description:
4934 Bring link down or up in the null-provider.
4935 params:
4936 begin - (string) One end of a device or switch.
4937 end - (string) the other end of the device or switch
4938 returns:
4939 main.TRUE if no exceptions were thrown and no Errors are
4940 present in the resoponse. Otherwise, returns main.FALSE
4941 '''
4942 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004943 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004944 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004945 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004946 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004947 if "Error" in response or "Failure" in response:
4948 main.log.error( response )
4949 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004950 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004951 except AssertionError:
4952 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004953 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004954 except TypeError:
4955 main.log.exception( self.name + ": Object not as expected" )
4956 return main.FALSE
4957 except pexpect.EOF:
4958 main.log.error( self.name + ": EOF exception found" )
4959 main.log.error( self.name + ": " + self.handle.before )
4960 main.cleanup()
4961 main.exit()
4962 except Exception:
4963 main.log.exception( self.name + ": Uncaught exception!" )
4964 main.cleanup()
4965 main.exit()
4966
Jon Hall2c8959e2016-12-16 12:17:34 -08004967 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004968 '''
4969 Description:
4970 Changes the state of port in an OF switch by means of the
4971 PORTSTATUS OF messages.
4972 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004973 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4974 port - (string) target port in the device. Ex: '2'
4975 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004976 returns:
4977 main.TRUE if no exceptions were thrown and no Errors are
4978 present in the resoponse. Otherwise, returns main.FALSE
4979 '''
4980 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004981 state = state.lower()
4982 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004983 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004984 response = self.sendline( cmd, showResponse=True )
4985 assert response is not None, "Error in sendline"
4986 assert "Command not found:" not in response, response
4987 if "Error" in response or "Failure" in response:
4988 main.log.error( response )
4989 return main.FALSE
4990 return main.TRUE
4991 except AssertionError:
4992 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004993 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004994 except TypeError:
4995 main.log.exception( self.name + ": Object not as expected" )
4996 return main.FALSE
4997 except pexpect.EOF:
4998 main.log.error( self.name + ": EOF exception found" )
4999 main.log.error( self.name + ": " + self.handle.before )
5000 main.cleanup()
5001 main.exit()
5002 except Exception:
5003 main.log.exception( self.name + ": Uncaught exception!" )
5004 main.cleanup()
5005 main.exit()
5006
5007 def logSet( self, level="INFO", app="org.onosproject" ):
5008 """
5009 Set the logging level to lvl for a specific app
5010 returns main.TRUE on success
5011 returns main.FALSE if Error occurred
5012 if noExit is True, TestON will not exit, but clean up
5013 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5014 Level defaults to INFO
5015 """
5016 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005017 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005018 self.handle.expect( "onos>" )
5019
5020 response = self.handle.before
5021 if re.search( "Error", response ):
5022 return main.FALSE
5023 return main.TRUE
5024 except pexpect.TIMEOUT:
5025 main.log.exception( self.name + ": TIMEOUT exception found" )
5026 main.cleanup()
5027 main.exit()
5028 except pexpect.EOF:
5029 main.log.error( self.name + ": EOF exception found" )
5030 main.log.error( self.name + ": " + self.handle.before )
5031 main.cleanup()
5032 main.exit()
5033 except Exception:
5034 main.log.exception( self.name + ": Uncaught exception!" )
5035 main.cleanup()
5036 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005037
5038 def getGraphDict( self, timeout=60, includeHost=False ):
5039 """
5040 Return a dictionary which describes the latest network topology data as a
5041 graph.
5042 An example of the dictionary:
5043 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5044 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5045 Each vertex should at least have an 'edges' attribute which describes the
5046 adjacency information. The value of 'edges' attribute is also represented by
5047 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5048 list of attributes.
5049 An example of the edges dictionary:
5050 'edges': { vertex2: { 'port': ..., 'weight': ... },
5051 vertex3: { 'port': ..., 'weight': ... } }
5052 If includeHost == True, all hosts (and host-switch links) will be included
5053 in topology data.
5054 """
5055 graphDict = {}
5056 try:
5057 links = self.links()
5058 links = json.loads( links )
5059 devices = self.devices()
5060 devices = json.loads( devices )
5061 idToDevice = {}
5062 for device in devices:
5063 idToDevice[ device[ 'id' ] ] = device
5064 if includeHost:
5065 hosts = self.hosts()
5066 # FIXME: support 'includeHost' argument
5067 for link in links:
5068 nodeA = link[ 'src' ][ 'device' ]
5069 nodeB = link[ 'dst' ][ 'device' ]
5070 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005071 if nodeA not in graphDict.keys():
5072 graphDict[ nodeA ] = { 'edges': {},
5073 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5074 'type': idToDevice[ nodeA ][ 'type' ],
5075 'available': idToDevice[ nodeA ][ 'available' ],
5076 'role': idToDevice[ nodeA ][ 'role' ],
5077 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5078 'hw': idToDevice[ nodeA ][ 'hw' ],
5079 'sw': idToDevice[ nodeA ][ 'sw' ],
5080 'serial': idToDevice[ nodeA ][ 'serial' ],
5081 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5082 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005083 else:
5084 # Assert nodeB is not connected to any current links of nodeA
5085 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005086 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5087 'type': link[ 'type' ],
5088 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005089 return graphDict
5090 except ( TypeError, ValueError ):
5091 main.log.exception( self.name + ": Object not as expected" )
5092 return None
5093 except KeyError:
5094 main.log.exception( self.name + ": KeyError exception found" )
5095 return None
5096 except AssertionError:
5097 main.log.exception( self.name + ": AssertionError exception found" )
5098 return None
5099 except pexpect.EOF:
5100 main.log.error( self.name + ": EOF exception found" )
5101 main.log.error( self.name + ": " + self.handle.before )
5102 return None
5103 except Exception:
5104 main.log.exception( self.name + ": Uncaught exception!" )
5105 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005106
5107 def getIntentPerfSummary( self ):
5108 '''
5109 Send command to check intent-perf summary
5110 Returns: dictionary for intent-perf summary
5111 if something wrong, function will return None
5112 '''
5113 cmd = "intent-perf -s"
5114 respDic = {}
5115 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005116 assert resp is not None, "Error in sendline"
5117 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005118 try:
5119 # Generate the dictionary to return
5120 for l in resp.split( "\n" ):
5121 # Delete any white space in line
5122 temp = re.sub( r'\s+', '', l )
5123 temp = temp.split( ":" )
5124 respDic[ temp[0] ] = temp[ 1 ]
5125
5126 except (TypeError, ValueError):
5127 main.log.exception( self.name + ": Object not as expected" )
5128 return None
5129 except KeyError:
5130 main.log.exception( self.name + ": KeyError exception found" )
5131 return None
5132 except AssertionError:
5133 main.log.exception( self.name + ": AssertionError exception found" )
5134 return None
5135 except pexpect.EOF:
5136 main.log.error( self.name + ": EOF exception found" )
5137 main.log.error( self.name + ": " + self.handle.before )
5138 return None
5139 except Exception:
5140 main.log.exception( self.name + ": Uncaught exception!" )
5141 return None
5142 return respDic
5143
Chiyu Chengec63bde2016-11-17 18:11:36 -08005144 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005145 """
5146 Searches the latest ONOS log file for the given search term and
5147 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005148
chengchiyu08303a02016-09-08 17:40:26 -07005149 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005150 searchTerm:
5151 The string to grep from the ONOS log.
5152 startLine:
5153 The term that decides which line is the start to search the searchTerm in
5154 the karaf log. For now, startTerm only works in 'first' mode.
5155 logNum:
5156 In some extreme cases, one karaf log is not big enough to contain all the
5157 information.Because of this, search mutiply logs is necessary to capture
5158 the right result. logNum is the number of karaf logs that we need to search
5159 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005160 mode:
5161 all: return all the strings that contain the search term
5162 last: return the last string that contains the search term
5163 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005164 num: return the number of times that the searchTerm appears in the log
5165 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005166 """
5167 try:
5168 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005169 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005170 logPath = '/opt/onos/log/karaf.log.'
5171 logPaths = '/opt/onos/log/karaf.log'
5172 for i in range( 1, logNum ):
5173 logPaths = logPath + str( i ) + " " + logPaths
5174 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005175 if startLine:
5176 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5177 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005178 if mode == 'all':
5179 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005180 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005181 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005182 elif mode == 'first':
5183 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5184 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005185 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005186 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005187 return num
You Wang6d301d42017-04-21 10:49:33 -07005188 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005189 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5190 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005191 else:
5192 main.log.error( self.name + " unsupported mode" )
5193 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005194 before = self.sendline( cmd )
5195 before = before.splitlines()
5196 # make sure the returned list only contains the search term
5197 returnLines = [line for line in before if searchTerm in line]
5198 return returnLines
5199 except AssertionError:
5200 main.log.error( self.name + " searchTerm is not string type" )
5201 return None
5202 except pexpect.EOF:
5203 main.log.error( self.name + ": EOF exception found" )
5204 main.log.error( self.name + ": " + self.handle.before )
5205 main.cleanup()
5206 main.exit()
5207 except pexpect.TIMEOUT:
5208 main.log.error( self.name + ": TIMEOUT exception found" )
5209 main.log.error( self.name + ": " + self.handle.before )
5210 main.cleanup()
5211 main.exit()
5212 except Exception:
5213 main.log.exception( self.name + ": Uncaught exception!" )
5214 main.cleanup()
5215 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005216
5217 def vplsShow( self, jsonFormat=True ):
5218 """
5219 Description: Returns result of onos:vpls show, which should list the
5220 configured VPLS networks and the assigned interfaces.
5221 Optional:
5222 * jsonFormat: enable json formatting of output
5223 Returns:
5224 The output of the command or None on error.
5225 """
5226 try:
5227 cmdStr = "vpls show"
5228 if jsonFormat:
5229 raise NotImplementedError
5230 cmdStr += " -j"
5231 handle = self.sendline( cmdStr )
5232 assert handle is not None, "Error in sendline"
5233 assert "Command not found:" not in handle, handle
5234 return handle
5235 except AssertionError:
5236 main.log.exception( "" )
5237 return None
5238 except TypeError:
5239 main.log.exception( self.name + ": Object not as expected" )
5240 return None
5241 except pexpect.EOF:
5242 main.log.error( self.name + ": EOF exception found" )
5243 main.log.error( self.name + ": " + self.handle.before )
5244 main.cleanup()
5245 main.exit()
5246 except NotImplementedError:
5247 main.log.exception( self.name + ": Json output not supported")
5248 return None
5249 except Exception:
5250 main.log.exception( self.name + ": Uncaught exception!" )
5251 main.cleanup()
5252 main.exit()
5253
5254 def parseVplsShow( self ):
5255 """
5256 Parse the cli output of 'vpls show' into json output. This is required
5257 as there is currently no json output available.
5258 """
5259 try:
5260 output = []
5261 raw = self.vplsShow( jsonFormat=False )
5262 namePat = "VPLS name: (?P<name>\w+)"
5263 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5264 encapPat = "Encapsulation: (?P<encap>\w+)"
5265 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5266 mIter = re.finditer( pattern, raw )
5267 for match in mIter:
5268 item = {}
5269 item[ 'name' ] = match.group( 'name' )
5270 ifaces = match.group( 'interfaces' ).split( ', ')
5271 if ifaces == [ "" ]:
5272 ifaces = []
5273 item[ 'interfaces' ] = ifaces
5274 encap = match.group( 'encap' )
5275 if encap != 'NONE':
5276 item[ 'encapsulation' ] = encap.lower()
5277 output.append( item )
5278 return output
5279 except Exception:
5280 main.log.exception( self.name + ": Uncaught exception!" )
5281 main.cleanup()
5282 main.exit()
5283
5284 def vplsList( self, jsonFormat=True ):
5285 """
5286 Description: Returns result of onos:vpls list, which should list the
5287 configured VPLS networks.
5288 Optional:
5289 * jsonFormat: enable json formatting of output
5290 """
5291 try:
5292 cmdStr = "vpls list"
5293 if jsonFormat:
5294 raise NotImplementedError
5295 cmdStr += " -j"
5296 handle = self.sendline( cmdStr )
5297 assert handle is not None, "Error in sendline"
5298 assert "Command not found:" not in handle, handle
5299 return handle
5300 except AssertionError:
5301 main.log.exception( "" )
5302 return None
5303 except TypeError:
5304 main.log.exception( self.name + ": Object not as expected" )
5305 return None
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 NotImplementedError:
5312 main.log.exception( self.name + ": Json output not supported")
5313 return None
5314 except Exception:
5315 main.log.exception( self.name + ": Uncaught exception!" )
5316 main.cleanup()
5317 main.exit()
5318
5319 def vplsCreate( self, network ):
5320 """
5321 CLI command to create a new VPLS network.
5322 Required arguments:
5323 network - String name of the network to create.
5324 returns:
5325 main.TRUE on success and main.FALSE on failure
5326 """
5327 try:
5328 network = str( network )
5329 cmdStr = "vpls create "
5330 cmdStr += network
5331 output = self.sendline( cmdStr )
5332 assert output is not None, "Error in sendline"
5333 assert "Command not found:" not in output, output
5334 assert "Error executing command" not in output, output
5335 assert "VPLS already exists:" 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 vplsDelete( self, network ):
5354 """
5355 CLI command to delete a VPLS network.
5356 Required arguments:
5357 network - Name of the network to delete.
5358 returns:
5359 main.TRUE on success and main.FALSE on failure
5360 """
5361 try:
5362 network = str( network )
5363 cmdStr = "vpls delete "
5364 cmdStr += network
5365 output = self.sendline( cmdStr )
5366 assert output is not None, "Error in sendline"
5367 assert "Command not found:" not in output, output
5368 assert "Error executing command" not in output, output
5369 assert " not found" not in output, output
5370 return main.TRUE
5371 except AssertionError:
5372 main.log.exception( "" )
5373 return main.FALSE
5374 except TypeError:
5375 main.log.exception( self.name + ": Object not as expected" )
5376 return main.FALSE
5377 except pexpect.EOF:
5378 main.log.error( self.name + ": EOF exception found" )
5379 main.log.error( self.name + ": " + self.handle.before )
5380 main.cleanup()
5381 main.exit()
5382 except Exception:
5383 main.log.exception( self.name + ": Uncaught exception!" )
5384 main.cleanup()
5385 main.exit()
5386
5387 def vplsAddIface( self, network, iface ):
5388 """
5389 CLI command to add an interface to a VPLS network.
5390 Required arguments:
5391 network - Name of the network to add the interface to.
5392 iface - The ONOS name for an interface.
5393 returns:
5394 main.TRUE on success and main.FALSE on failure
5395 """
5396 try:
5397 network = str( network )
5398 iface = str( iface )
5399 cmdStr = "vpls add-if "
5400 cmdStr += network + " " + iface
5401 output = self.sendline( cmdStr )
5402 assert output is not None, "Error in sendline"
5403 assert "Command not found:" not in output, output
5404 assert "Error executing command" not in output, output
5405 assert "already associated to network" not in output, output
5406 assert "Interface cannot be added." not in output, output
5407 return main.TRUE
5408 except AssertionError:
5409 main.log.exception( "" )
5410 return main.FALSE
5411 except TypeError:
5412 main.log.exception( self.name + ": Object not as expected" )
5413 return main.FALSE
5414 except pexpect.EOF:
5415 main.log.error( self.name + ": EOF exception found" )
5416 main.log.error( self.name + ": " + self.handle.before )
5417 main.cleanup()
5418 main.exit()
5419 except Exception:
5420 main.log.exception( self.name + ": Uncaught exception!" )
5421 main.cleanup()
5422 main.exit()
5423
5424 def vplsRemIface( self, network, iface ):
5425 """
5426 CLI command to remove an interface from a VPLS network.
5427 Required arguments:
5428 network - Name of the network to remove the interface from.
5429 iface - Name of the interface to remove.
5430 returns:
5431 main.TRUE on success and main.FALSE on failure
5432 """
5433 try:
5434 iface = str( iface )
5435 cmdStr = "vpls rem-if "
5436 cmdStr += network + " " + iface
5437 output = self.sendline( cmdStr )
5438 assert output is not None, "Error in sendline"
5439 assert "Command not found:" not in output, output
5440 assert "Error executing command" not in output, output
5441 assert "is not configured" not in output, output
5442 return main.TRUE
5443 except AssertionError:
5444 main.log.exception( "" )
5445 return main.FALSE
5446 except TypeError:
5447 main.log.exception( self.name + ": Object not as expected" )
5448 return main.FALSE
5449 except pexpect.EOF:
5450 main.log.error( self.name + ": EOF exception found" )
5451 main.log.error( self.name + ": " + self.handle.before )
5452 main.cleanup()
5453 main.exit()
5454 except Exception:
5455 main.log.exception( self.name + ": Uncaught exception!" )
5456 main.cleanup()
5457 main.exit()
5458
5459 def vplsClean( self ):
5460 """
5461 Description: Clears the VPLS app configuration.
5462 Returns: main.TRUE on success and main.FALSE on failure
5463 """
5464 try:
5465 cmdStr = "vpls clean"
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 main.FALSE
5473 except TypeError:
5474 main.log.exception( self.name + ": Object not as expected" )
5475 return main.FALSE
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 Exception:
5482 main.log.exception( self.name + ": Uncaught exception!" )
5483 main.cleanup()
5484 main.exit()
5485
5486 def vplsSetEncap( self, network, encapType ):
5487 """
5488 CLI command to add an interface to a VPLS network.
5489 Required arguments:
5490 network - Name of the network to create.
5491 encapType - Type of encapsulation.
5492 returns:
5493 main.TRUE on success and main.FALSE on failure
5494 """
5495 try:
5496 network = str( network )
5497 encapType = str( encapType ).upper()
5498 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5499 cmdStr = "vpls set-encap "
5500 cmdStr += network + " " + encapType
5501 output = self.sendline( cmdStr )
5502 assert output is not None, "Error in sendline"
5503 assert "Command not found:" not in output, output
5504 assert "Error executing command" not in output, output
5505 assert "already associated to network" not in output, output
5506 assert "Encapsulation type " not in output, output
5507 return main.TRUE
5508 except AssertionError:
5509 main.log.exception( "" )
5510 return main.FALSE
5511 except TypeError:
5512 main.log.exception( self.name + ": Object not as expected" )
5513 return main.FALSE
5514 except pexpect.EOF:
5515 main.log.error( self.name + ": EOF exception found" )
5516 main.log.error( self.name + ": " + self.handle.before )
5517 main.cleanup()
5518 main.exit()
5519 except Exception:
5520 main.log.exception( self.name + ": Uncaught exception!" )
5521 main.cleanup()
5522 main.exit()
5523
5524 def interfaces( self, jsonFormat=True ):
5525 """
5526 Description: Returns result of interfaces command.
5527 Optional:
5528 * jsonFormat: enable json formatting of output
5529 Returns:
5530 The output of the command or None on error.
5531 """
5532 try:
5533 cmdStr = "interfaces"
5534 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005535 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005536 cmdStr += " -j"
5537 handle = self.sendline( cmdStr )
5538 assert handle is not None, "Error in sendline"
5539 assert "Command not found:" not in handle, handle
5540 return handle
5541 except AssertionError:
5542 main.log.exception( "" )
5543 return None
5544 except TypeError:
5545 main.log.exception( self.name + ": Object not as expected" )
5546 return None
5547 except pexpect.EOF:
5548 main.log.error( self.name + ": EOF exception found" )
5549 main.log.error( self.name + ": " + self.handle.before )
5550 main.cleanup()
5551 main.exit()
5552 except NotImplementedError:
5553 main.log.exception( self.name + ": Json output not supported")
5554 return None
5555 except Exception:
5556 main.log.exception( self.name + ": Uncaught exception!" )
5557 main.cleanup()
5558 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005559
5560 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5561 '''
5562 Get the timestamp of searchTerm from karaf log.
5563
5564 Arguments:
5565 splitTerm_before and splitTerm_after:
5566
5567 The terms that split the string that contains the timeStamp of
5568 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5569 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5570 and the splitTerm_after is "x"
5571
5572 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005573 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005574 '''
5575 if logNum < 0:
5576 main.log.error("Get wrong log number ")
5577 return main.ERROR
5578 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5579 if len(lines) == 0:
5580 main.log.warn( "Captured timestamp string is empty" )
5581 return main.ERROR
5582 lines = lines[ 0 ]
5583 try:
5584 assert type(lines) is str
5585 # get the target value
5586 line = lines.split( splitTerm_before )
5587 key = line[ 1 ].split( splitTerm_after )
5588 return int( key[ 0 ] )
5589 except IndexError:
5590 main.log.warn( "Index Error!" )
5591 return main.ERROR
5592 except AssertionError:
5593 main.log.warn( "Search Term Not Found " )
5594 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005595
5596 def workQueueAdd( self, queueName, value ):
5597 """
5598 CLI command to add a string to the specified Work Queue.
5599 This function uses the distributed primitives test app, which
5600 gives some cli access to distributed primitives for testing
5601 purposes only.
5602
5603 Required arguments:
5604 queueName - The name of the queue to add to
5605 value - The value to add to the queue
5606 returns:
5607 main.TRUE on success, main.FALSE on failure and
5608 main.ERROR on error.
5609 """
5610 try:
5611 queueName = str( queueName )
5612 value = str( value )
5613 prefix = "work-queue-test"
5614 operation = "add"
5615 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5616 output = self.distPrimitivesSend( cmdStr )
5617 if "Invalid operation name" in output:
5618 main.log.warn( output )
5619 return main.ERROR
5620 elif "Done" in output:
5621 return main.TRUE
5622 except TypeError:
5623 main.log.exception( self.name + ": Object not as expected" )
5624 return main.ERROR
5625 except Exception:
5626 main.log.exception( self.name + ": Uncaught exception!" )
5627 main.cleanup()
5628 main.exit()
5629
5630 def workQueueAddMultiple( self, queueName, value1, value2 ):
5631 """
5632 CLI command to add two strings to the specified Work Queue.
5633 This function uses the distributed primitives test app, which
5634 gives some cli access to distributed primitives for testing
5635 purposes only.
5636
5637 Required arguments:
5638 queueName - The name of the queue to add to
5639 value1 - The first value to add to the queue
5640 value2 - The second value to add to the queue
5641 returns:
5642 main.TRUE on success, main.FALSE on failure and
5643 main.ERROR on error.
5644 """
5645 try:
5646 queueName = str( queueName )
5647 value1 = str( value1 )
5648 value2 = str( value2 )
5649 prefix = "work-queue-test"
5650 operation = "addMultiple"
5651 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5652 output = self.distPrimitivesSend( cmdStr )
5653 if "Invalid operation name" in output:
5654 main.log.warn( output )
5655 return main.ERROR
5656 elif "Done" in output:
5657 return main.TRUE
5658 except TypeError:
5659 main.log.exception( self.name + ": Object not as expected" )
5660 return main.ERROR
5661 except Exception:
5662 main.log.exception( self.name + ": Uncaught exception!" )
5663 main.cleanup()
5664 main.exit()
5665
5666 def workQueueTakeAndComplete( self, queueName, number=1 ):
5667 """
5668 CLI command to take a value from the specified Work Queue and compelte it.
5669 This function uses the distributed primitives test app, which
5670 gives some cli access to distributed primitives for testing
5671 purposes only.
5672
5673 Required arguments:
5674 queueName - The name of the queue to add to
5675 number - The number of items to take and complete
5676 returns:
5677 main.TRUE on success, main.FALSE on failure and
5678 main.ERROR on error.
5679 """
5680 try:
5681 queueName = str( queueName )
5682 number = str( int( number ) )
5683 prefix = "work-queue-test"
5684 operation = "takeAndComplete"
5685 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5686 output = self.distPrimitivesSend( cmdStr )
5687 if "Invalid operation name" in output:
5688 main.log.warn( output )
5689 return main.ERROR
5690 elif "Done" in output:
5691 return main.TRUE
5692 except TypeError:
5693 main.log.exception( self.name + ": Object not as expected" )
5694 return main.ERROR
5695 except Exception:
5696 main.log.exception( self.name + ": Uncaught exception!" )
5697 main.cleanup()
5698 main.exit()
5699
5700 def workQueueDestroy( self, queueName ):
5701 """
5702 CLI command to destroy the specified Work Queue.
5703 This function uses the distributed primitives test app, which
5704 gives some cli access to distributed primitives for testing
5705 purposes only.
5706
5707 Required arguments:
5708 queueName - The name of the queue to add to
5709 returns:
5710 main.TRUE on success, main.FALSE on failure and
5711 main.ERROR on error.
5712 """
5713 try:
5714 queueName = str( queueName )
5715 prefix = "work-queue-test"
5716 operation = "destroy"
5717 cmdStr = " ".join( [ prefix, queueName, operation ] )
5718 output = self.distPrimitivesSend( cmdStr )
5719 if "Invalid operation name" in output:
5720 main.log.warn( output )
5721 return main.ERROR
5722 return main.TRUE
5723 except TypeError:
5724 main.log.exception( self.name + ": Object not as expected" )
5725 return main.ERROR
5726 except Exception:
5727 main.log.exception( self.name + ": Uncaught exception!" )
5728 main.cleanup()
5729 main.exit()
5730
5731 def workQueueTotalPending( self, queueName ):
5732 """
5733 CLI command to get the Total Pending items of the specified Work Queue.
5734 This function uses the distributed primitives test app, which
5735 gives some cli access to distributed primitives for testing
5736 purposes only.
5737
5738 Required arguments:
5739 queueName - The name of the queue to add to
5740 returns:
5741 The number of Pending items in the specified work queue or
5742 None on error
5743 """
5744 try:
5745 queueName = str( queueName )
5746 prefix = "work-queue-test"
5747 operation = "totalPending"
5748 cmdStr = " ".join( [ prefix, queueName, operation ] )
5749 output = self.distPrimitivesSend( cmdStr )
5750 pattern = r'\d+'
5751 if "Invalid operation name" in output:
5752 main.log.warn( output )
5753 return None
5754 else:
5755 match = re.search( pattern, output )
5756 return match.group(0)
5757 except ( AttributeError, TypeError ):
5758 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5759 return None
5760 except Exception:
5761 main.log.exception( self.name + ": Uncaught exception!" )
5762 main.cleanup()
5763 main.exit()
5764
5765 def workQueueTotalCompleted( self, queueName ):
5766 """
5767 CLI command to get the Total Completed items of the specified Work Queue.
5768 This function uses the distributed primitives test app, which
5769 gives some cli access to distributed primitives for testing
5770 purposes only.
5771
5772 Required arguments:
5773 queueName - The name of the queue to add to
5774 returns:
5775 The number of complete items in the specified work queue or
5776 None on error
5777 """
5778 try:
5779 queueName = str( queueName )
5780 prefix = "work-queue-test"
5781 operation = "totalCompleted"
5782 cmdStr = " ".join( [ prefix, queueName, operation ] )
5783 output = self.distPrimitivesSend( cmdStr )
5784 pattern = r'\d+'
5785 if "Invalid operation name" in output:
5786 main.log.warn( output )
5787 return None
5788 else:
5789 match = re.search( pattern, output )
5790 return match.group(0)
5791 except ( AttributeError, TypeError ):
5792 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5793 return None
5794 except Exception:
5795 main.log.exception( self.name + ": Uncaught exception!" )
5796 main.cleanup()
5797 main.exit()
5798
5799 def workQueueTotalInProgress( self, queueName ):
5800 """
5801 CLI command to get the Total In Progress items of the specified Work Queue.
5802 This function uses the distributed primitives test app, which
5803 gives some cli access to distributed primitives for testing
5804 purposes only.
5805
5806 Required arguments:
5807 queueName - The name of the queue to add to
5808 returns:
5809 The number of In Progress items in the specified work queue or
5810 None on error
5811 """
5812 try:
5813 queueName = str( queueName )
5814 prefix = "work-queue-test"
5815 operation = "totalInProgress"
5816 cmdStr = " ".join( [ prefix, queueName, operation ] )
5817 output = self.distPrimitivesSend( cmdStr )
5818 pattern = r'\d+'
5819 if "Invalid operation name" in output:
5820 main.log.warn( output )
5821 return None
5822 else:
5823 match = re.search( pattern, output )
5824 return match.group(0)
5825 except ( AttributeError, TypeError ):
5826 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5827 return None
5828 except Exception:
5829 main.log.exception( self.name + ": Uncaught exception!" )
5830 main.cleanup()
5831 main.exit()